前言

约定格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
├── aliyun                                             # 云厂商实例文件
│ └── aliyun_ecs_mod_demo # 模型名
│ └── aliyun_china_platform_7111 # 云账号名
│ └── ecs_instance_name_20241224121212 # 实例名
│ ├── backend.tf # 实例state文件保存说明:oss
│ └── main.tf # 实例具体的参数
├── modules # 模型数据文件夹
│ ├── aliyun # 云厂商模型文件夹
│ │ └── aliyun_ecs_mod_demo # 模型名
│ │ ├── main.tf # 模型定义主文件
│ │ ├── outputs.tf # 模型定义输出文件
│ │ └── variables.tf # 模型定义参数文件
│ └── tenmod # 另一个云厂商模型
└── tenent # 另一个云厂商实例文件

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
.
├── modules
│ └── tcloud
│ └── tcloud_ckafka_mod_demo
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── tcloud
└── tcloud_ckafka_demo
└── tcloud_china_game_x6
└── ckafaka_demo_202501221738
├── backend.tf
└── main.tf

modules

/modules/tcloud/tcloud_ckafka_mod_demo/main.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
terraform {
required_providers {
tencentcloud = {
source = "tencentcloudstack/tencentcloud"
}
}
}

provider "tencentcloud" {
region = var.region
}

data "tencentcloud_availability_zones_by_product" "zone" {
name = var.availability_zone
product = "ckafka"
}

resource "tencentcloud_ckafka_instance" "this" {
instance_name = var.instance_name
zone_id = data.tencentcloud_availability_zones_by_product.zone.zones[0].id
vpc_id = var.vpc_id
subnet_id = var.vswitch_id
msg_retention_time = var.msg_retention_time
kafka_version = var.kafka_version
disk_size = var.disk_size
band_width = var.band_width
disk_type = var.disk_type
partition = var.partition
charge_type = var.charge_type



config {
auto_create_topic_enable = var.auto_create_topic_enable
default_num_partitions = var.num_partitions
default_replication_factor = var.replication_factor
}

dynamic_retention_config {
enable = var.dynamic_retention_config_enable
}

}

/modules/tcloud/tcloud_ckafka_mod_demo/outputs.tf

1
2
3
output "ckafka_instance_id" {
value = tencentcloud_ckafka_instance.this.id
}

/modules/tcloud/tcloud_ckafka_mod_demo/variables.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
variable "region" {
description = "地域"
type = string
default = "ap-shanghai"
}

variable "instance_name" {
description = "kafka实例名"
type = string
}

variable "availability_zone" {
# 如ap-shanghai-2
description = "可用区"
type = string
}

variable "charge_type" {
# PREPAID(预付费), POSTPAID_BY_HOUR(按量付费)
description = "kafka实例计费方式"
type = string
validation {
condition = contains(["PREPAID", "POSTPAID_BY_HOUR"], var.charge_type)
error_message = "The charge_type must be one of PREPAID, POSTPAID_BY_HOUR"
}
}

variable "kafka_version" {
# 0.10.2/1.1.1/2.4.1/2.8.1
description = "kafka实例版本"
type = string
validation {
condition = contains(["0.10.2", "1.1.1", "2.4.1", "2.4.2", "2.8.1"], var.kafka_version)
error_message = "The kafka_version must be one of 0.10.2, 1.1.1, 2.4.1, 2.4.2, 2.8.1"
}
}


variable "vswitch_id" {
// 阿里云vswitch_id -> 腾讯云subnet_id
description = "绑定子网id"
type = string
}

variable "vpc_id" {
description = "绑定vpc_id"
type = string
}

variable "disk_size" {
# 需满足当前实例的计费规格,此处预设200和400,可以根据需要修改
description = "kafka实例磁盘规格"
type = number
validation {
condition = contains([200, 400], var.disk_size)
error_message = "The disk_size must be one of 200, 400"
}
}

variable "disk_type" {
# 专业版实例磁盘类型,标准版实例不需要填写,CLOUD_SSD(SSD云硬盘), CLOUD_BASIC(高性能云硬盘)
description = "kafka专业版实例磁盘类型"
type = string
default = ""
validation {
condition = contains(["", "CLOUD_SSD", "CLOUD_BASIC"], var.disk_type)
error_message = "The disk_type must be empty, or one of CLOUD_SSD, CLOUD_BASIC"
}
}

variable "band_width" {
# 单位为MBps.
description = "kafka实例带宽"
type = number
}

variable "auto_create_topic_enable" {
description = "是否自动创建topic"
type = bool
default = true
validation {
condition = contains([true, false], var.auto_create_topic_enable)
error_message = "The auto_create_topic_enable must be one of true, false"
}
}

variable "num_partitions" {
description = "kafka实例默认分区数"
type = number
default = 3
}

variable "replication_factor" {
description = "kafka实例默认副本数"
type = number
default = 2
}

variable "dynamic_retention_config_enable" {
description = "是否启用动态消息保留时间配置"
type = number
default = 0
validation {
condition = contains([0, 1], var.dynamic_retention_config_enable)
error_message = "The dynamic_retention_config_enable must be one of 0, 1"
}
}

variable "msg_retention_time" {
# 以分钟为单位
description = "kafka实例日志的最大保留时间"
type = number
default = 10080
}

variable "partition" {
description = "kafka实例分区大小"
type = number
default = 3
}

Demo

/tcloud/tcloud_ckafka_demo/tcloud_china_game_x6/ckafaka_demo_202501221738/backend.tf

1
2
3
4
5
6
7
8
9
terraform {
backend "oss" {
endpoint = "oss-cn-hangzhou.aliyuncs.com"
bucket = "dz-devops" # 替换为你的 OSS Bucket 名称
prefix = "terraform_state/tcloud/tcloud_ckafka_demo/tcloud_china_game_x6/ckafka_demo_202501221738"
key = "terraform.tfstate" # 存储状态文件的路径和名称
region = "cn-hangzhou" # OSS 的地域(根据你的实际情况调整)
}
}

/tcloud/tcloud_ckafka_demo/tcloud_china_game_x6/ckafaka_demo_202501221738/main.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module "ckafka_instance" {
source = "../../../../modules/tcloud/tcloud_ckafka_mod_demo"
region = "ap-shanghai"
instance_name = "ckafka-test"
availability_zone = "ap-shanghai-2"
charge_type = "POSTPAID_BY_HOUR"
kafka_version = "2.4.2"
vpc_id = "vpc-4tkroxts"
vswitch_id = "subnet-oy1pqvzv"
disk_size = 200
# disk_type = "CLOUD_BASIC"
band_width = 20
auto_create_topic_enable = true
num_partitions = 3
replication_factor = 3
dynamic_retention_config_enable = 1
msg_retention_time = 1300
partition = 400
}

运行测试

获取 AK/SK

在首次使用 Terraform 之前,需要前往腾讯云的云 API 密钥页面申请安全凭证SecretId和SecretKey2。若已有可使用的安全凭证,则跳过该步骤2。具体步骤如下2:

  1. 登录腾讯云访问管理控制台,在左侧导航栏,选择访问密钥>API 密钥管理。
  2. 在API 密钥管理页面,单击新建密钥,即可以创建一对SecretId/SecretKey。

设置环境变量

将获取到的SecretId和SecretKey设置为环境变量:

1
2
export TENCENTCLOUD_SECRET_ID=your_secret_id
export TENCENTCLOUD_SECRET_KEY=your_secret_key

运行项目

进入项目根目录,这里是ckafaka_demo_202501221738目录:

1
cd ./tcloud/tcloud_ckafka_demo/tcloud_china_game_x6/ckafaka_demo_202501221738/

初始化 Terraform 项目:

1
2
# 将xxx替换为实际backend的ak,将yyy替换为实际backend的sk
terraform init -backend-config="access_key=xxx" -backend-config="secret_key=yyy"

该命令会下载所需的插件和依赖,并初始化后端配置。
类似的输出(首次使用某一个provier时,会先下载):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Initializing the backend...

Successfully configured the backend "oss"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing modules...
- ckafka_instance in ../../../../modules/tcloud/tcloud_ckafka_mod_demo
Initializing provider plugins...
- Finding latest version of tencentcloudstack/tencentcloud...
- Installing tencentcloudstack/tencentcloud v1.81.162...
- Installed tencentcloudstack/tencentcloud v1.81.162 (signed by a HashiCorp partner, key ID 84F69E1C1BECF459)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

预览计划变更:

1
terraform plan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Reading...
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Read complete after 0s [id=2066006299]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# module.ckafka_instance.tencentcloud_ckafka_instance.this will be created
+ resource "tencentcloud_ckafka_instance" "this" {
+ band_width = 20
+ charge_type = "POSTPAID_BY_HOUR"
+ disk_size = 200
+ disk_type = "CLOUD_BASIC"
+ id = (known after apply)
+ instance_name = "ckafka-test"
+ instance_type = (known after apply)
+ kafka_version = "kafka_version"
+ max_message_byte = (known after apply)
+ msg_retention_time = 1300
+ partition = 400
+ public_network = (known after apply)
+ renew_flag = (known after apply)
+ specifications_type = "profession"
+ subnet_id = "subnet-oy1pqvzv"
+ tag_set = (known after apply)
+ upgrade_strategy = 1
+ vip = (known after apply)
+ vpc_id = "vpc-4tkroxts"
+ vport = (known after apply)
+ zone_id = 200002

+ config {
+ auto_create_topic_enable = true
+ default_num_partitions = 3
+ default_replication_factor = 3
}

+ dynamic_retention_config {
+ bottom_retention = (known after apply)
+ disk_quota_percentage = (known after apply)
+ enable = 1
+ step_forward_percentage = (known after apply)
}

+ tags (known after apply)
}

Plan: 1 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

执行变更:

1
terraform apply
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Reading...
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Read complete after 1s [id=2066006299]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# module.ckafka_instance.tencentcloud_ckafka_instance.this will be created
+ resource "tencentcloud_ckafka_instance" "this" {
+ band_width = 20
+ charge_type = "POSTPAID_BY_HOUR"
+ disk_size = 200
+ disk_type = "CLOUD_BASIC"
+ id = (known after apply)
+ instance_name = "ckafka-test"
+ instance_type = (known after apply)
+ kafka_version = "kafka_version"
+ max_message_byte = (known after apply)
+ msg_retention_time = 1300
+ partition = 400
+ public_network = (known after apply)
+ renew_flag = (known after apply)
+ specifications_type = "profession"
+ subnet_id = "subnet-oy1pqvzv"
+ tag_set = (known after apply)
+ upgrade_strategy = 1
+ vip = (known after apply)
+ vpc_id = "vpc-4tkroxts"
+ vport = (known after apply)
+ zone_id = 200002

+ config {
+ auto_create_topic_enable = true
+ default_num_partitions = 3
+ default_replication_factor = 3
}

+ dynamic_retention_config {
+ bottom_retention = (known after apply)
+ disk_quota_percentage = (known after apply)
+ enable = 1
+ step_forward_percentage = (known after apply)
}

+ tags (known after apply)
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

module.ckafka_instance.tencentcloud_ckafka_instance.this: Creating...
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [10s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [20s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [30s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [40s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [50s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m0s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m10s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m20s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m30s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m40s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [1m50s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m0s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m10s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m20s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m30s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m40s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [2m50s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Still creating... [3m0s elapsed]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Creation complete after 3m7s [id=ckafka-9jnda3jn]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

验证创建

在前端查看是否成功创建实例:

img_1

销毁资源

执行下面的命令进行销毁:

1
terraform destroy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Reading...
module.ckafka_instance.data.tencentcloud_availability_zones_by_product.zone: Read complete after 1s [id=2066006299]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Refreshing state... [id=ckafka-9jnda3jn]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

# module.ckafka_instance.tencentcloud_ckafka_instance.this will be destroyed
- resource "tencentcloud_ckafka_instance" "this" {
- band_width = 20 -> null
- charge_type = "POSTPAID_BY_HOUR" -> null
- disk_size = 200 -> null
- disk_type = "CLOUD_BASIC" -> null
- id = "ckafka-9jnda3jn" -> null
- instance_name = "ckafka-test" -> null
- instance_type = 1 -> null
- kafka_version = "0.10.2.1" -> null
- msg_retention_time = 1300 -> null
- partition = 400 -> null
- public_network = 3 -> null
- renew_flag = 0 -> null
- specifications_type = "profession" -> null
- subnet_id = "subnet-oy1pqvzv" -> null
- tag_set = {} -> null
- upgrade_strategy = 1 -> null
- vip = "172.17.0.3" -> null
- vpc_id = "vpc-4tkroxts" -> null
- vport = "9092" -> null
- zone_id = 200002 -> null

- config {
- auto_create_topic_enable = true -> null
- default_num_partitions = 3 -> null
- default_replication_factor = 3 -> null
}

- dynamic_retention_config {
- bottom_retention = 0 -> null
- disk_quota_percentage = 0 -> null
- enable = 1 -> null
- step_forward_percentage = 0 -> null
}
}

Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes

module.ckafka_instance.tencentcloud_ckafka_instance.this: Destroying... [id=ckafka-9jnda3jn]
module.ckafka_instance.tencentcloud_ckafka_instance.this: Destruction complete after 5s

Destroy complete! Resources: 1 destroyed.

验证销毁

img_2