资源是Terraform体系中最重要的组成元素, 每个资源块用来定义一个或多个基础产品实例, 它或者定义一个VPC,或者定义一个CVM或者一条DNS记录.
每个资源可能有多个特性支持, 则需要十几或者几十个字段, 但创建此资源我们只提供最少的子集即可.如腾讯云的CVM全量需要30+个字段,但我们只需要5个字段就可以定义出一个CVM.
resource "tencentcloud_redis_instance" "test" {
availability_zone = "ap-guangzhou-3"
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
}
一个资源块的定义需要四部分组成:关键字, 类型, 本地名字,资源配置
类型和本地名字唯一确定一个资源, 所以可以认为是全局唯一(其实是模块内唯一,模块可以认为是资源定义的namespace)
上面我们定义一个redis的实例,位于"广州三区", 内存大小为8G,密码为test12345789,实例类型为主从redis,这个是定义一个redis的最小集合,其他的参数都采用默认参数
如port为6379, 名字让服务器端随机生成.
云上的每个产品功能都有一个或者多个资源进行定义,在编写这些资源排版代码时会决定这个资源管理云上的那个产品的那个功能,如定义
每一个资源类型都属于一个特定的provider,此provider需要云厂商来开发, 以rpc插件的形式提供给terrform,terraform-provider-tencentcloud是我们提供的插件,提供大部分腾讯云产品资源封装
当选择好类型后,资源配置也随着确定,资源配置字段包含三个方面
A.排版资源需要的特性字段
如上例子中的password,mem_size.这些是能创建云上产品必须的一些字段
B.terraform支持的表达式
terraform支持部分表达式语法,如条件表达式condition ? true_val : false_val, 循环表达式for s in var.list : upper(s)等
C.terraform支持的元参数
本章后面会详细介绍
terraform要求接入云厂商提供规范化文档方便客户使用,当我们熟悉terraform后大部分时间都画在研究这些文档上.我们腾讯云提供的文档在 here
左列是云产品分类和资源类型,右列是这个此资源类型如何配置使用,全英文环境.
写好的资源块只存在于本地的配置文件,是我们创建云上资源的意图, 并没有在云平台上进行实施.
执行apply操作,此配置就会开始在云上进行产品的创建.执行destroy操作,云上的产品就开始销毁.
当我们执行完apply操作时, 新的配置块会将云上创建新的产品并保存在本地的state文件中,以便我们后序修改和删除.
对于那些旧的配置块,会和本地的state文件进行对比,如有修改则调用腾讯云的openapi进行修改,如有删除同样调用openapi进行删除.
大部分资源都不会对其他资源产生依赖,terraform可以并发的对资源进行创建,修改和删除.当时总有一些时候,资源之间会有依赖,或者是因为这些资源就是这样工作的,如mysql的帐号类型必须是在mysql实例创建完成会才能创建,或者是因为依赖其他资源的生成的一些信息.如dns要依赖lb生成的外网ip
一般情形下依赖关系可以自主处理,terraform处理的方式是根据资源块之间的字段依赖来形成有向图,遍历有向图形成排序关系,当资源创建,修改或者销毁时,会根据排序关系依次创建.
大多是资源对其他资源的依赖都是字段的依赖,因此通常不必指定资源之间的依赖性.
然而总有一些依赖是没法通过字段来引用的, 这时候就需要元参数depends_on来解决这种隐藏的依赖,如使用cdn产品依赖域名备案, 但是cdn产品字段不会引用域名备案的任何字段
现在的terraform定义下下面6个元参数来影响资源行为,分别是
处理terraform不能自动推断出来的依赖关系, 主要处理的是依赖其他资源但是不依赖这些资源的任何字段
因为有的产品还没有封装进terraform-provider-tencentcloud, 在现有的支持产品情形下没有找到比较好的例子,所以例子先空缺,等以后产品丰富了在进行补充.
默认的情况下,资源块配置的是一个产品实例,在实际项目中我们可能要创建一批同配置的产品实例,这时候就可以用count来定义,如创建3个同样配置的redis可用
resource "tencentcloud_redis_instance" "test" {
availability_zone = "ap-guangzhou-3"
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
count=3
name="redis_${count.index}"
}
当我们在资源块配置中使用count后,count.index表达式就会起效,标识当前的产品实例在资源块配置是的顺序编码,从0开始.
上面会创建3个redis,官网控制台可查看名字分别为redis_0,redis_1和redis_2
如果引用某个产品实例,普通的可以通过<TYPE>.<NAME>进行引用,而带有count的则要通用<TYPE>.<NAME><INDEX>的形式进行引用,如我们要引用第2个实例服务端分配的ip,可以通过
tencentcloud_redis_instance.test1.ip的形式
count要求各个实例的配置是一样的(除了可以通过count.index稍微达到差异),而for_each可以提供更个性配置方式
有此场景我们准备创建一个命名为orange的redis内存为1024,另一个命名为banana内存为8192,除此之外其他的配置都一样, 则可以用下面的形式
resource "tencentcloud_redis_instance" "test" {
for_each = {
orange = 1024
banana = 8192
}
availability_zone = "ap-guangzhou-3"
type = "master_slave_redis"
password = "test12345789"
name=each.key
mem_size = each.value
}
当我们在资源块配置中使用for_each后,each.key和each.value两个表达式就会起效
each.key表示for_each遍历的map或者set的key
each.value表示for_each遍历的map或者set的value,在set情形下each.key==each.value
用for_each创建的资源进行引用需要通过<TYPE>.<NAME><KEY>的形式进行,如我们需要名称为banana的redis实例的ip,则需要通过tencentcloud_redis_instance.test"banana".ip的形式
一般情形下一个provider配置一个region+aksk,如果我们想创建多个地区的资源就可以用provider元参数,它可以定义我们创建此资源使用另一个provider.
备选provider需要指定别名, 资源引用此provider采用<PROVIDER>.<ALIAS>的形式.
备选provider的配置会覆盖默认provider的配置
provider "tencentcloud" {
secret_id = "AKIDPT**********nOxvJdjbR3"
secret_key = "XoqmT7WlkU******oJZaMzZ4ThfC2h6v"
region = "ap-guangzhou"
}
provider "tencentcloud" {
alias = "shanghai"
region = "ap-shanghai"
}
resource "tencentcloud_redis_instance" "test" {
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
}
resource "tencentcloud_redis_instance" "test" {
provider = tencentcloud.shanghai
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
}
我们在上海和广州各创建一个redis(因为redis az必须指定,此例子不能正常执行,大家可用cvm代替)
资源的生命周期可以参考上文的资源行为, lifecycle作用是定义资源行为中的一些小细节
resource "tencentcloud_redis_instance" "test" {
availability_zone = "ap-guangzhou-3"
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
lifecycle {
create_before_destroy = true
}
}
resource "tencentcloud_redis_instance" "test" {
availability_zone = "ap-guangzhou-3"
type = "master_slave_redis"
password = "test12345789"
mem_size = 8192
name = "redis"
lifecycle {
ignore_changes = [
name,
]
}
}
resource "tencentcloud_key_pair" "foo" {
key_name = "examplekey"
public_key = file("~/.ssh/id_rsa.pub")
}
resource "tencentcloud_instance" "my_awesome_app" {
key_name = aws_key_pair.example.key_name
connection {
type = "ssh"
user = "root"
private_key = file("~/.ssh/id_rsa")
host = self.ip
}
provisioner "remote-exec" {
inline = [
"sudo yum -y install nginx",
"sudo systemctl start nginx"
]
}
}
有的资源编写的时候支持可以设置资源行为时间,如下边的资源可以设置create/update/delete的超时时间,并设置默认时间分别为40/80/40分钟
同时我们也可以在资源配置块中指定行为的超时时间,3s表示3秒, 4m表示4分钟,5h表示5小时
resource "tencentcloud_example_instance" "example" {
# ...
timeouts {
create = "60m"
delete = "2h"
}
}
注意的是大部分资源不支持可配置超时,我们腾讯云的没有一个资源支持可配置超时.
以上就是terraform的基本使用方式.有什么疑问可以找我们组或者点击
here进行反馈.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。