赞
踩
基础设施即代码(Infrastructure-as-Code,IaC)意味着使用代码来定义和管理基础设施,用户不必在每次开发、 测试或部署软件时都配置环境。所有基础设施参数都以称为清单的文件的形式保存。
开发人员对基础设施配置文件进行编码,并将其存储在版本控制中。如果有人编辑了一个文件,拉取请求和代码审查 工作流可以检查更改的正确性。因此,与所有代码文件一样,清单易于重用、编辑、复制和共享,它使构建、测试、准备 和部署基础设施更快、更一致。
服务器自动化和配置管理工具通常可以用来实现 IaC。当然,也有一些专门针对 IaC 的解决方案。 一些常见的方案 如下:
采用基础设施即代码的方法有两种。尽管两种方法都能让大多数 IaC 工具正常运行,使用哪一种取决于手上的任务。
声明式方法也称为功能性方法,明确定义了系统的理想状态,但未明确指出达到该状态的方法。这种方法可让您明确 名义想要的资源,包括必需的属性。IaC 软件会自动配置理想的基础设施,声明式 IaC 工具将会自动应用作出的任何改 变。声明式 IaC 可多次执行且结果相同,无需人为干预。既声明式通常都是幂等的。
如:AWS CloudFormation、hashcrop Terraform、Puppet。
相比之下,命令式方法可让您明确定义配置基础设施的方式,以及实现的方法。命令式方法也叫作过程式方法,明确定义了实现特定配置所需的命令。之后需要按照正确的顺序执行这些命令,一次一个步骤。这个方法较脆弱,依靠的是明确的指示,不接受任何更新。需要改变时,命令式 IaC 工具将会要求操作员解读应如何应用这些改变。
如:Chef、Ansible。
但也并不是说声明式就比编程式要好,而是要根据场景使用适合的工具
Terraform比Ansible更适合作为基础云资源、IAAS层的管理工具。
当通过代码完成了基础设施的创建,而且创建出来的资源就是按照我们声明文件中那样描述的那样。这其实就是基础设施即代码的一种技术实现。基础设施即代码是一种使用新的技术来构建和管理动态基础设施的方式。它把基础设施、工具和服务以及对基础设施的管理本身作为一个软件系统,采纳软件工程实践以结构化的安全的方式来管理对系统的变更。基础设施即代码有四项关键原则:
再生性:环境中的任何元素可以轻松复制。
一致性:无论何时,创建的环境各个元素的配置是完全相同的。
快速反馈:能够频繁、容易地进行变更,并快速知道变更是否正确。
可见性:所有对环境的变更应该容易理解、可审计、受版本控制。
Terraform 是一种安全有效地构建、更改和版本控制基础设施的工具(基础架构自动化的编排工具)。它的目标是 "Write, Plan, and create Infrastructure as Code"(编写、规划和创建基础架构作为代码), 基础架构即代码。
Terraform 几乎可以支持所有市面上能见到的云服务。具体的说就是可以用代码来管理维护 IT 资源,把之前需要手动操作的一部分任务通过程序来自动化的完成,这样的做的结果非常明显:高效、不易出错。
Terraform 提供了对资源和提供者的灵活抽象。该模型允许表示从物理硬件、虚拟机和容器到电子邮件和 DNS 提供者的所有内容。由于这种灵活性,Terraform 可以用来解决许多不同的问题。这意味着有许多现有的工具与Terraform 的功能重叠。但是需要注意的是,Terraform 与其他系统并不相互排斥。它可以用于管理小到单个应用程序或达到整个数据中心的不同对象。
Terraform 使用配置文件描述管理的组件(小到单个应用程序,达到整个数据中心)。Terraform 生成一个执行计划,描述它将做什么来达到所需的状态,然后执行它来构建所描述的基础结构。随着配置的变化,Terraform 能够确定发生了什么变化,并创建可应用的增量执行计划。
Terraform 是用 Go 语言开发的开源项目,你可以在 github 上访问到它的源代码。
什么叫资源编排?类似于 AWS控制台 、腾讯云控制台这些控制台,可以管理你的所有云资源,Terraform和控制台作用一样,本质都是管理你的云资源,只不过,控制台是界面化的操作,而Terraform是通过配置文件来实现。
控制台的界面化操作,也许并不是最佳的管理工具,这时候,Terraform可能就是上古神器了。
使用高级配置语法来描述基础架构,这样就可以对数据中心的蓝图进行版本控制,就像对待其他代码一样对待它。
Terraform 有一个 plan 步骤,它生成一个执行计划。执行计划显示了当执行 apply 命令时 Terraform 将做什么。通过 plan 进行提前检查,可以使 Terraform 操作真正的基础结构时避免意外。
Terraform 构建的所有资源的图表,它能够并行地创建和修改任何没有相互依赖的资源。因此,Terraform 可以高效地构建基础设施,操作人员也可以通过图表深入地解其基础设施中的依赖关系。
把复杂的变更集应用到基础设施中,而无需人工交互。通过前面提到的执行计划和资源图,我们可以确切地知道 Terraform 将会改变什么,以什么顺序改变,从而避免许多可能的人为错误。
terraform通过provider去调用云厂商的API去进行资源调用。
“基础设施即代码(Infrastructure as Code)”,这里的Code就是对基础设施资源的代码定义和描述,也就是通过代码表达我们想要管理的资源。
- # VPC 资源
- resource "alicloud_vpc" "vpc" {
- name = "tf_vpc"
- cidr_block = "172.16.0.0/16"
- }
- # VSwitch 资源
- resource "alicloud_vswitch" "vswitch" {
- vpc_id = alicloud_vpc.vpc.id
- cidr_block = "172.16.1.0/24"
- availability_zone = "cn-beijing-a"
- }
Terraform 通常用于对云上基础设施,如虚拟机,网络资源,容器资源,存储资源等的创建,更新,查看,删除等管理动作,也可以实现对物理机的管理,如安装软件,部署应用等。
【Provider】 是一个与Open API直接交互的后端驱动,Terraform 就是通过Provider来完成对基础设施资源的管理的。不同的基础设施提供商都需要提供一个Provider来实现对自家基础设施的统一管理。目前Terraform目前支持超过160多种的providers,大多数云平台的Provider插件均已经实现了,阿里云对应的Provider为 alicloud 。
在Terraform中,一个具体的资源或者服务称之为一个resource,比如一台ECS 实例,一个VPC网络,一个SLB实例。每个特定的resource包含了若干可用于描述对应资源或者服务的属性字段,通过这些字段来定义一个完整的资源或者服务,比如实例的名称(name),实例的规格(instance_type),VPC或者VSwitch的网段(cidr_block)等。
定义一个Resource的语法非常简单,通过 resource
关键字声明,如下:
- # 定义一个ECS实例
- resource "alicloud_instance" "default" {
- image_id = "ubuntu_16_04_64_20G_alibase_20190620.vhd"
- instance_type = "ecs.sn1ne.large"
- instance_name = "my-first-vm"
- system_disk_category = "cloud_ssd"
- ...
- }
alicloud_instance
为资源类型(Resource Type),定义这个资源的类型,告诉Terraform这个Resource是阿里云的ECS实例还是阿里云的VPC。default
为资源名称(Resource Name),资源名称在同一个模块中必须唯一,主要用于供其他资源引用该资源。显然这个Terraform模板的功能为在阿里云上创建一个ECS实例,镜像ID为 ubuntu_16_04_64_20G_alibase_20190620.vhd
,规格为 ecs.sn1ne.large
,自定义了实例名称和系统盘的类型。
除此之外,在Terraform中,一个资源与另一个资源的关系也定义为一个资源,如一块云盘与一台ECS实例的挂载,一个弹性IP(EIP)与一台ECS或者SLB实例的绑定关系。这样定义的好处是,一方面资源架构非常清晰,另一方面,当模板中有若干个EIP需要与若干台ECS实例绑定时,只需要通过Terraform的 count
功能就可以在无需编写大量重复代码的前提下实现绑定功能。
- resource "alicloud_instance" "default" {
- count = 5
- ...
- }
- resource "alicloud_eip" "default" {
- count = 5
- ...
- }
- resource "alicloud_eip_association" "default" {
- count = 5
- instance_id = alicloud_instance.default[count.index].id
- allocation_id = alicloud_eip.default[count.index].id
- }
显然这个Terraform模板的功能为在阿里云上创建5个ECS实例和5个弹性IP,并将它们一一绑定。
对资源的查询是运维人员或者系统最常使用的操作,比如,查看某个region下有哪些可用区,某个可用区下有哪些实例规格,每个region下有哪些镜像,当前账号下有多少机器等,通过对资源及其资源属性的查询可以帮助和引导开发者进行下一步的操作。
除此之外,在编写Terraform模板时,Resource使用的参数有些是固定的静态变量,但有些情况下可能参数变量不确定或者参数可能随时变化。比如我们创建ECS 实例时,通常需要指定我们自己的镜像ID和实例规格,但我们的模板可能随时更新,如果在代码中指定ImageID和Instance,则一旦我们更新镜像模板就需要重新修改代码。
在Terraform 中,Data Source 提供的就是一个查询资源的功能,每个data source实现对一个资源的动态查询,Data Souce的结果可以认为是动态变量,只有在运行时才能知道变量的值。
Data Sources通过 data
关键字声明,如下:
- // Images data source for image_id
- data "alicloud_images" "default" {
- most_recent = true
- owners = "system"
- name_regex = "^ubuntu_18.*_64"
- }
-
- data "alicloud_zones" "default" {
- available_resource_creation = "VSwitch"
- enable_details = true
- }
-
- // Instance_types data source for instance_type
- data "alicloud_instance_types" "default" {
- availability_zone = data.alicloud_zones.default.zones.0.id
- cpu_core_count = 2
- memory_size = 4
- }
-
- resource "alicloud_instance" "web" {
- image_id = data.alicloud_images.default.images[0].id
- instance_type = data.alicloud_instance_types.default.instance_types[0].id
- instance_name = "my-first-vm"
- system_disk_category = "cloud_ssd"
- ...
- }
如上例子中的ECS Instance 没有指定镜像ImageID和实例规格,而是通过 data
引用,Terraform运行时将首先根据镜像名称前缀选择系统镜像,如果同时有多个镜像满足条件,则选择最新的镜像。实例规格也是类似,在某个可用区下选择2核4G的实例规格进行返回。
Terraform创建和管理的所有资源都会保存到自己的数据库上,这个数据库不是通常意义上的数据库(MySQL,Redis等),而是一个文件名为 terraform.tfstate
的文件,在Terraform 中称之为 state,默认存放在执行Terraform命令的本地目录下。这个 state
文件非常重要,如果该文件损坏,Terraform 将认为已创建的资源被破坏或者需要重建(实际的云资源通常不会受到影响),因为在执行Terraform命令是,Terraform将会利用该文件与当前目录下的模板做Diff比较,如果出现不一致,Terraform将按照模板中的定义重新创建或者修改已有资源,直到没有Diff,因此可以认为Terraform是一个有状态服务。
当涉及多人协作时不仅需要拷贝模板,还需要拷贝 state
文件,这无形中增加了维护成本。幸运的是,目前Terraform支持把 state
文件放到远端的存储服务 OSS
上或者 consul
上,来实现 state
文件和模板代码的分离。具体细节可参考官方文档Remote State或者关注后续文章的详细介绍。
正如上节提到,Terraform 在创建完资源后,会将资源的属性存放在一个 state
文件中,这个文件可以存放在本地也可以存放在远端。存放 state
文件的载体就是 Backend 。Backend
分为本地(local)和远端(remote)两类,默认为本地。远端的类型也非常多,目前官方网站提供的有13种,并且阿里云的OSS就位列其中。
使用远端的Backend,既可以降低多人协作时对state的维护成本,而且可以将一些敏感的数据存放在远端,保证了数据的安全性。
Provisioner 通常用来在本地机器或者登陆远程主机执行相关的操作,如 local-exec
provisioner 用来执行本地的命令, chef
provisioner 用来在远程机器安装,配置和执行chef client, remote-exec
provisioner 用来登录远程主机并在其上执行命令。
Provisioner 通常跟 Provider一起配合使用,provider用来创建和管理资源,provisioner在创建好的机器上执行各种操作。
Terraform 运行时会读取工作目录中所有的 *.tf, *.tfvars 文件,所以我们不必把所有的东西都写在单个文件中去,应按职责分列在不同的文件中,例如:
1)provider.tf -- provider 配置
2)terraform.tfvars -- 配置 provider 要用到的变量
3)varable.tf -- 通用变量
4)resource.tf -- 资源定义
5)data.tf -- 包文件定义
6)output.tf -- 输出
Terraform引用了一些环境变量来控制部分功能,这些环境变量都不是必需的,但是可以改变一些Terraform的默认行为,帮助用户适配更多应用场景
- # 操作日志是重要的运维信息来源,用户可以通过设置日志类型TF_LOG和日志保存路径TF_LOG_PATH,将详细的日志打印到stderr,以获取调试信息。TF_LOG支持五种可用值,TRACE,DEBUG,INFO,WARN,ERROR,分别代表五种不同的日志级别,其中TRACE表示最详细的日志
- export TF_LOG=TRACE # DEBUG INFO WARN ERROR
- export TF_LOG_PATH=/root/optf/tf.log
variable
是Terraform重要的配置文件类型之一,通过对变量的集中管理,用户可以在资源文件中直接引用变量名进行赋值。首先需要先定义(声明)变量,放到一个.tf
文件中,如:
创建variable.tf
文件,配置参数的默认值
- variable "access_key" {}
- variable "secret_key" {}
- variable "region" {
- default = "us-east-1"
- }
- variable "f5user" {
- type = string
- default = "admin"
- }
- variable "f5pass" {
- type = string
- default = "admin"
- }
上面定义了变量。前两个变量是空的,第三个给了一个默认值(默认参数)。此时运行terraform plan
,Terraform会提示输入这些尚未定义的变量。
引用变量,使用${var.xxx}
的形式。这样在资源配置文件中,参数可以直接调用var.f5user
- provider "aws" {
- access_key = "${var.access_key}"
- secret_key = "${var.secret_key}"
- region = "${var.region}"
- }
前面我们声明了变量,但是还没有给变量赋值,无法真正使用。给变量赋值,有以下几种方法,下面几种方法按照变量赋值的优先顺序排序。
使用terraform的各种命令时,使用-var
选项,可以在后面直接跟变量的定义,如:
- # terraform apply \
- -var 'access_key=foo'
- -var 'secret_key=bar'
- # ...
以这种方式赋值变量是一次性的,并不会保存它们的值,也就是说下一次重新执行命令时,需要重新赋值。
在terraform apply中,直接设置变量值会覆盖掉variable.tf
中设置的默认值
为永久性存储一个变量的值,可以将其放在文件中保存。Terraform会自动加载当前目录下扩展名为.tfvars
和.auto.tfvars
的文件来填充定义的变量。如果以其他格式存放,可以使用-var-file
选项来手动指定需要加载的变量值文件。这些文件使用Terraform格式或JSON格式。
使用文件也方便版本控制,但是用户名、密码这种东西就不要用版本控制管理的。因此可以将用户名和密码这类信息单独放在一个文件中,使用-var-file
来手动指定。其他的,可以自动填充,方便使用版本控制管理的,可以直接放在.tfvars
文件中,Terraform会自动加载。
Terraform会读取TF_VAR_name
这种格式的环境变量,用来填充定义好的变量。比如,环境变量中有一个TF_VAR_access_key
的变量,Terraform就会读取到,并用于填充access_key
变量。
如果某个变量没有采用以上任何一种方法来进行赋值,那么如果在变量的定义中有个default
属性,那么Terraform就会使用default
的值来对变量进行赋值。
没有使用任何方法来对变量赋值,在输入命令时使得Terraform不知道如何处理,此时就会出现交互界面,让用户手动输入变量值,来给变量赋值。
也可以利用TF_VAR_name
把变量设置在环境变量中
export TF_VAR_f5user="admin"
配置TF_INPUT
,可以关闭对未指定值的变量的提示。将刚才的variable.tf
中设置的参数删除
export export TF_INPUT=1
执行Terraform指令,会要求写入参数值
设置TF_INPUT
为false
或0
,再次执行指令,系统报错:未指定变量的值
export export TF_INPUT=0
用户可以通过CLI的配置文件对CLI进行一些设置,适用于所有Terraform的工作目录,与资源配置文件是区分开的。
配置文件中支持的参数有:
① 是否开启更新与安全检查:disable_checkpoint
② 允许更新与安全检查,但禁止使用匿名id删除警告消息:disable_checkpoint_signature
③ 启用插件缓存,以字符串的形式指定插件缓存目录的位置:plugin_cache_dir
④ Terraform企业版凭证:credentials
可以在环境变量中配置CLI Config File的位置
export TF_CLI_CONFIG_FILE="$HOME/.terraformrc-custom"
二进制文件:
Install | Terraform | HashiCorp Developer
https://releases.hashicorp.com/terraform/
官网:Terraform | HashiCorp Developer
Terraform 的安装非常简单,直接把官方提供的二进制可执行文件保存到本地就可以了。比如笔者习惯性的把它保存到 /usr/local/bin/ 目录下,当然这个目录会被添加到 PATH 环境变量中。完成后检查一下版本号:$
- $ wget https://releases.hashicorp.com/terraform/0.12.5/terraform_0.12.5_linux_amd64.zip
- $ unzip terraform_0.12.5_linux_amd64.zip
新建目录downloads,将安装好的terraform文件保存在该目录下
- // Move terraform
-
- $ mkdir downloads
-
- $ mv terraform downloads/
进入配置文件~/.profile添加Terraform的环境变量
- $ vim ~/.profile
-
- // Add terraform PATH
-
- export PATH="$PATH:~/downloads"
重新加载~/.profile文件
$ source ~/.profile
https://www.terraform.io/downloads.html
可二进制安装,也可命令行下载安装;
- $ brew tap hashicorp/tap
- Running `brew update --auto-update`...
- ==> Auto-updated Homebrew!
- Updated 3 taps (hashicorp/tap, homebrew/core and homebrew/cask).
- ==> New Formulae
- c3c hashicorp/tap/tfstacks libnsgif nowplaying-cli ruby@3.2 terrapin-scanner zigmod
- csvlens helm-ls libspelling rathole scnlib tomlplusplus zipkin
- doltgres k8sgpt limesuite rattler-build senpai urlscan
- git-grab kiota ncmdump rsyncy steamguard-cli vulkan-volk
- ==> New Casks
- aqua bugdom2 emby insomnium lyricsfinder nightshade shadow-bot theiaide wakatime
- bitbox domzilla-caffeine ia-presenter jyutping markedit prettyclean taccy ttu-base-suite znote
-
- You have 16 outdated formulae installed.
-
- $ brew install hashicorp/tap/terraform
- ==> Fetching hashicorp/tap/terraform
- ==> Downloading https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_darwin_arm64.zip
- ########################################################################################################################################################################### 100.0%
- ==> Installing terraform from hashicorp/tap
- 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/184908推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。