一、Azure Providers

Terraform 作为同一个可以可扩展的工具,是通过 Provider 来支持新的基础架构。Provider 是上游API的逻辑抽象。他们负责理解API交互并暴露资源。我们可以将 Provider 可以理解为各个云厂商提供的与云资源交互的后端驱动,不同的基础设施提供商都需要提供一个Provider来实现对自家基础设施的统一管理,例如我们熟知的 Azure,AWS,GCP,Kubernetes,Aliyun等等。根据官方罗列的 官方 Providers 和验证过的 Providers,超过了600多个。大家可以点击此连接查看具体的 Terraform Providers :https://registry.terraform.io/browse/providers。那么我们想指定 Terraform Azure Provider 怎么写?

provider "azurerm" {
  version = "~>2.0"
  features {}
}

version ="~>2.0" ,表示我们要使用 azure provider 的版本为 >2.0

features:表示自定义某些Azure提供程序资源的行为,我们目前使用的是 azure provider 的版本 2.x,如果使用的 azure provider 的版本为 1.x,则不需要 features

terraform init 来验证以上的解释

(1)provider version > 2.0

terraform集成到devops terraform datasource详解_azure

(2)provider version = 1.33

terraform集成到devops terraform datasource详解_azure_02

二、基本的Terraform 配置文件

resource "azurerm_resource_group" "example" {
  name = "Web_Test_TF_RG"
  location = "East Asia"
}

resource:表示我们将创建类型为 “azurerm_resource_group” 新的资源组

example:表示我们为当前新创建的资源组的 terraform module 起的名称。当前新创建的资源组,我们为其定义了两个参数,分别为 “name” 和 “location”

name:表示为当前即将创建的资源组的名称为 “Web_Test_TF_RG

location:表示当前资源组所在的位置为 “East Asia

terraform plan: 接下就是执行部署计划的过程了

三、Terraform 状态管理

terraform apply

执行计划部署完成后,会在Terraform 项目文件夹中生成 “terraform.tfstate” 的文件和 “.terraform.tfstate.lock.info”的文件。

terraform集成到devops terraform datasource详解_云计算_03

 terraform.tfstate:当前文件中包含了因为它包含有关已部署到Azure的内容的所有状态信息

terraform集成到devops terraform datasource详解_Terraform_04

terraform.tfstate.lock.info:这个文件从名字上就可以看出来,部署过程中加锁。这时候就有人疑惑了,为什么要加锁 ?原因很简单,就那操作数据库来说,对同一数据的修改,或者删除的时候,需要加锁处理。这里的terraform 的状态文件加锁也是同样的道理。

四、Terraform扩展知识点

其实我们都知道,Azure 有好几个版本,我们一般常用的就是 Azure Global,Azure China,如果我们在 Azure Provider 中不指定哪个Azure 环境,Terraform 会默认认为我们是将云资源部署在 Azure Global 上的。如果我们用的是Azure China(世纪互联版的Azure),那我就必须得在 Provider 中指定Azure 环境。environment 的值可能为:

public(默认)

usgovernment

german

china

注意:如果不想在Provider 中指定云环境,我们可以设置环境变量:

setx ARM_ENVIRONMENT china

完整示例:

provider "azurerm" {
  version = "~>2.0"
  environment = "china"
  features {}
}

五、变量 (var)

为了使代码更DRY化和可配置化,terraform允许用户定义输入变量。输入变量、输出变量。变量语法

varible "NAME" {
  [CONFIG ...]
}

变量声明包含3个参数:

description:描述参数用来说明如何使用这个变量

default:有多种方法可以为变量赋值,包含

命令行(-var)

terraform plan -var "server_port = 8080"

文件(-var-file):环境变量(TF_VAR_<variable_name>)

export TF_VAR_server_port = 8080

type:允许对用户输入的变量类型进行强制约束;

包含string、number、bool、list、map、set、object、tuple、any(默认约束类型为any)

string:字符串

variable "map_example" {
  description = "an example of a map in terrform"
  type        = map(string)
  
  default     = {
    key1      = "value1"
    key2      = "value2"
    key3      = "value3"
  }
}

number:数字

variable "number_example" {
  description = "an example of a number variable in terraform"
  type        = number
  default     =2
}

list:列表为字符串

variable "list_example" {
  description = "an example of a list in terraform"
  type        = list
  default     = ["a","b","c"]
}

列表为数字

variable "list_number_example" {
  description = "an example of a number list in terraform"
  type        = list(number)
  default     = [1,2,3]
}

更加复杂的对象和元祖结构类型

variable "object_example" {
  description = "an example of a structural type in terraform"
  type        = object({
    name      = string
    age       = number
    tags      = list(string)
    enabled   = bool
  })
  default     = {
    name      = "value"
    age       = 18
    tags      = ["a","b","c"]
    enabled   = true
  }
}

注意:如果变量设置的与类型约束不匹配的值,terraform会报错

name为字符串

age为数字

tags为字符串列表

enabled为布尔值

例如在某个配置文件需要配置一个端口的变量

variable "server_port" {
    description = "The port the server will use for HTTP requests"
    type = number
}

如果没有输入默认的变量,执行plan或者apply会显示下面提示

# terraform plan
var.server_port
  The port the server will use for HTTP requests

  Enter a value:

如果不想每次处理交互式提示,可以通过命令的形式为变量提供初始化

# export TF_VAR_server_port=8080  
# terraform plan

直接设定一个默认值

variable "server_port" {
    description = "The port the server will use for HTTP requests"
    type = number
    default = 8080
}

变量引用:语法如下

var.<VARIABLE_NAME>

具体配置

resource "aws_security_group" "instance" {
    name = "terraform-example-instance"

    ingress {
      cidr_blocks = [ "0.0.0.0/0" ]
      description = "mono"
      from_port = var.server_port
      protocol = "TCP"
      to_port = var.server_port
    }      
}

输出变量

output "<NAME>" {
    value = <VALUE>
    [CONFIG]
}
output "public_ip" {
  value        = aws_instance.example.public_ip
  description  = "public ip"
}

注意 你要执行apply执行才会显示IP,如果执行plan会显示下面信息

Changes to Outputs:
  + public_ip = (known after apply)

正确output输入

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

Outputs:

public_ip = "18.183.127.183"

可以将新创建的服务器的IP地址作为变量输出在命令行上,而不必跟以前一样,登录AWS控制台查看IP地址或者

# terraform output public_ip
18.183.127.183

六、附录

参考资料:Terraform 官方Terraform 注册表