为了能够在本机更快速、高效执行TF脚本,本文先做一个配置,来实现加速相关Provider下载。
一、加速AliyunProvider读取每次运行terraforminit命令时,Terraform会下载部署所需要的Provider,每次下载耗时很长,我们可以提前下载好Provider,例如下载到/srv/terraform-plugins目录下(Provider下载路径)
注意:目录格式如下:
1.1使用Provider缓存添加环境变量:
exportTF_PLUGIN_CACHE_DIR="/srv/terraform-plugins"
在~/.terraformrc中增加plugin_cache_dir:
注意:配置完之后,可以通过命令行查看是否生效:
ConfiguretheAlicloudProviderterraform{required_providers{alicloud={source="aliyun/alicloud"version="1.127.0"}}required_version="=0.12"}provider"alicloud"{access_key="需要有权限访问OSS与OTS,其中OTS是用于加锁,oss是保存state数据ecs_role_name="EcsRamRole"}}4.2Provisioner:在机器上执行操作的组件Provisioner通常用来在本地机器或者登陆远程主机执行相关的操作,如local-execprovisioner用来执行本地的命令,chefprovisioner用来在远程机器安装,配置和执行chefclient,remote-execprovisioner用来登录远程主机并在其上执行命令。
Provisioner通常跟Provider一起配合使用,provider用来创建和管理资源,provisioner在创建好的机器上执行各种操作。
思考:结合Provider+Provisioner就可以实现基础设施层面的IaC加上应用配置层面的。完整的一套配置管理工具
4.3Module:简化你的TF模板Module是Terraform为了管理单元化资源而设计的,是子节点,子资源,子架构模板的整合和抽象。在实际复杂的技术架构中,涉及到的资源多种多样,资源与资源之间的关系错综复杂,资源模版的编写,扩展,维护等多个问题的成本都会不断增加。将多种可以复用的资源定义为一个module,通过对module的管理简化模板的架构,降低模板管理的复杂度,这就是module的作用。
对资源进行分类,将每一类资源用一个单独的目录进行管理,最后用一个模板来管理所有的目录,进而完成对所有资源及资源关系的串联,如下所示:
├──├──├──├──modules/│├──vpc/││├──││├──││├──│├──slb/││├──││├──││├──│├──ecs/│├──rds/│├──oss/
接下来,用统一的模版将这些目录关联起来,如下所示:
//VPCmodulemodule"vpc"{source="./modules/vpc"name="new-netwtok"}//WebTiermodulemodule"web"{source="./modules/ecs"instance_count=2vswitch_ids="${_vswitch_ids}"}4.4语法4.4.1数据类型
JSON格式
TF语法
Boolean
booltrue/false
Number
number
String
string
EOT
hello
world
EOT
如果要保持格式可以这样写:
value=-EOT
hello
world
EOT
生成JSON或YAML。可以通过关键字jsonencode如:
example=jsonencode(
{
a=1
b="hello"
})
Object
map(){name="",age=52}
["keyname"]获取map中的值
Array
list()["",""]
[3]获取第三个元素值
Null
null不带引号的符号表示null
逻辑指令
%{ifBOOL}/{else}/{if}
"Hello,%{!=""}${}%{else}unnamed%{if}"%{forNAMEinCOLLECTION}/%{for}
EOT%{foripinaws_*.private_ip}server${ip}%{for}EOTEOT%{foripinaws_*.private_ip~}server${ip}%{for~}EOT操作符
*/%+-====!=||
内置函数。min()keys()
三元表达式:condition?true:false
for表达式.[:upper(s)],[fork,:length(k)+length(v)]
locals{admin_users={forname,:name=_admin}regular_users={forname,:name=userif!_admin}}Groupingresults
variable"users"{type=map(object({role=string}))}locals{users_by_role={forname,:=name}}内转函数
Encoding
String
Numeric
Collection
Filesystem
HashandCrypto
IPNetwork
DateTime
4.4.2代码注释
支持几种类型:
//或list(string)default=""description=""}variable"availability_zone_names"{type=list(string)default=["us-west-1a"]}variable"docker_ports"{type=list(object({internal=numberexternal=numberprotocol=string}))default=[{internal=8300external=8300protocol="tcp"}]}variable"user_information"{type=object({name=stringaddress=string})sensitive=true}resource"some_resource""a"{name=_=_}
变量类型支持:
listTYPE
setTYPE
mapTYPE
object
tuple
output
output"application_account_id"{value=""description="Outputapplicationaccountid."sensitive=truedeps_on=["",""]}local
locals{Commontagstobeassignedtoallresourcescommon_tags={Service=_nameOwner=}}tags=_tags}相关参数说明
resource
resource"aws_instance""server"{count=4Createoneinstanceforeachsubnetcount=length(_ids)ami="ami-a1b2c3d4"instance_type=""subnet_id=_ids[]tags={Name="Server${}"}}terraform
terraform{back"oss"{bucket="bucket-with-terraform-state"prefix="path/mystate"key="1.tfstate"region="cn-hangzhou"tablestore_point=""tablestore_table="statelock"#是为了做OSS的权限用的ecs_role_name="EcsRamRole"}required_providers{alicloud={source="aliyun/alicloud"version="1.127.0"}}required_version="=0.12"}4.5代码片段赏析TBD
五、解决方案5.1纳管存量资源这个解决方案用于以下4个场景:
场景一:长期使用控制台、阿里云CLI、资源编排服务或者直接调用API创建和管理资源,初次使用Terraform的场景。
场景二:长期使用Terraform管理资源,如果通过控制台对单个云资源做属性变更,希望保持原有的资源状态(State)一致的场景。
场景三:所有资源都定义在一个模板中,想要对原有模板进行重构拆分,以降低随着资源不断增多而带来的模板和state的管理复杂度的场景。
场景四:想要将新版Provider中新增的参数同步到原文档中的场景。
Terraform对资源的导入可以分为三个步骤:
获取资源ID:基于资源ID查询资源并获取其属性。
1、获取资源ID。对资源ID的获取可以通过Web控制台,CLI,API等多种方式,最简单的方式是通过Terraform的DataSource,输入简单的查询条件,例如获取一个ECS实例:
$tfimportalicloud__:ImportingfromID"i-bp18s06o9bc53n32"alicloud_:Importprepared!Preparedalicloud_instanceforimportalicloud_:Refreshingstate[id=i-bp18s06o9bc53n32]Importsuccessful!gedbyTerraform.
3、补齐资源模板定义。由于模板中没有完成对所导入资源的详细定义,因此,资源导入成功后,模板内容与State存储的内容存在差异(State里面的内容是完整的,但模板的内容是空白的).
为了保持资源模板与资源状态的一致,需要在模板中手动补齐缺失的参数定义,直到运行plan不会再有变更信息为止.所要补齐的内容主要以那些引起更新的字段为主,补齐完成后运行terraformplan进行测试:
在执行plan之后直到出现Nochanges表示完成5.2通过TF+Ansible实现整体自动化运维
思路:TF中的provider用来创建和管理资源,provisioner在创建好的机器上执行各种操作。
5.3通过Jenkins+TF搭建基础设施的CI/CDTBD
六、生态体系6.1合规审计:terraform-complianceterraform-compliance用于合规审计,优点在于该插件是和provider无关的。
用户可以自定义合规规则(使用Behavior-DrivenDevelopmentBDD——目前常用的BDD测试框架有Ruby中的Cucumber,Python中的Behave等),比如“不能给任何Ram角色赋予AdministratorAccess权限”,这些规则存储在features中;
Cucumber中几个专业术语
Features文件:
Feature:功能,下面可以由多个Scenario
Scenario:场景,下面可以由多个Steps
Steps:步骤使用Given、When、Then、But、And这些关键词
Step_definitions文件:根据Features文件中的Steps编写测试代码
在Terraformplan后,将plan结果存储在.out文件中,使用terraform-compliance对两者进行比对,判断是否合规。
7、参考资料AlibabaCloudProvider
官方手册
GOOGLE相关文章