Bruce Blog Bruce Blog
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航

Bruce Tao

运维界的该溜子
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航
  • Ansible

  • Terraform

    • terraform命令使用
    • terraform概述
    • terraform基础
    • terraform语法
      • Backend配置
      • 阿里云实践
      • 腾讯云实践
      • 华为云实践
      • Docker实践
      • AWS实践
      • Terraform扩展
      • Azure实践
      • K8S实践
    • AWS

    • Cloud
    • Terraform
    Bruce
    2022-10-27
    目录

    terraform语法

    # 一、内容介绍

    • Provider插件
    • Resource资源
    • DataSuource数据源
    • Variable变量
    • Output输出

    # 二、语法介绍

    • Terraform的配置文件都是以.tf为后缀;
    • Terraform支持两种模式HCL、JSON;
    • HashiCorp Configuration Language

    # 三、Provider插件

    • Terraform通过provider管理基础设施,使用provider与云供应商API进行交互;
    • 每个Provider都包含相关的资源呵呵数据源;
    • provider: https://registry.terraform.io/browse/providers

    image-20220906163244749

    # 声明Provider
    • 每个Terrform模块必须声明它需要哪些Provider,以便Terraform可以安装和使用它们.
    • 提供者要求在一个required_providers块中.
    ## versions.tf
    terraform {
      required_version = "1.2.8" // 这里是terraform的版本号,可以通过`terraform -v`获取到
      required_providers {
        alicloud = {
          //原地址
          source  = "aliyun/alicloud"
          //版本
          version = "1.183.0"
        }
      }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 声明Provider
    • 关键字provider
    • Provider名称
    # provider.tf
    
    provider "alicloud" {
    	access_key = var.alicloud_access_key
    	secret_key = var.alicloud_secret_key
    	region = var.region
    }
    
    
    provider "PROVIDER_NAME" {
    	//主题部分
    	//配置参数
    	access_key = var.alicloud_access_key
    	secret_key = var.alicloud_secret_key
    	region = var.region
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # alias-配置多个Provider
    • 可以为同一个Provider定义多个配置,并选择基于每个资源或每个模块使用哪一个.这样做的主要原因是支持一个云平台的多个区域
    • 引用方式: ., alicloud.beijing
    # provider.tf
    provider "alicloud" {
    	alias = "beijing"
    	region = "cn-beijng-b"
    }
    
    # provider.tf
    provider "alicloud" {
    	alias = "hanzhou"
    	region = "cn-hanzhou-b"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 四、Resource资源

    • 资源来自Provider,是Terraform中最重要的元素.每个资源块描述一个或多个基础对象,例如网络、计算实例或更高级别的组件,例如DNS记录.
    • 资源名称必须以字母或下划线开头,并且只能包含字母、数字、下划线和破折号
    resource "resource_type" "name" {
    	// resource_config
    }
    
    1
    2
    3
    # Resource-ECS
    • 定义一台ECS实例: 可用区、安全组、实例规格、系统盘类型、镜像、实例名称、带宽、交换机、付费类型、账户密码
    • https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance
    # alicloud-ecs.tf
    resource "alicloud_instance" "myecs" {
      provider                   = alicloud.shanghai
      availability_zone          = "cn-shanghai-b"
      security_groups            = alicloud_security_group.group.*.id
      instance_type              = "ecs.g7.large"
      system_disk_category       = "cloud_essd"
      system_disk_name           = "tf_system_disk_name"
      system_disk_description    = "tf_system_disk_description"
      image_id                   = "centos_7_5_x64_20G_alibase_20211130.vhd"
      instance_name              = "mytestecs"
      vswitch_id                 = alicloud_vswitch.vsw.id
      internet_max_bandwidth_out = 1
      internet_charge_type       = "PayByTraffic"
      password                   = "root@123"
    
    #   data_disks {
    #     name        = "disk2"
    #     size        = 20
    #     category    = "cloud_efficiency"
    #     description = "disk2"
    #     encrypted   = true
    #     kms_key_id  = alicloud_kms_key.key.id
    #   }
    }
    
    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
    # Resource-DNS
    • 定义一条DNS解析记录: ZoneName: terraform.chsaos.com; Type: A; Record: demo
    • 完整域名: terraform.chsaos.com
    • 需要在阿里云RAM给子账号添加DNS的权限
    # alicloud_dns.tf
    # TYPE A
    #  terraform.chsaos.com
    
    reource "alicloud_dns_record" "record" {
    	name = "chsaos.com"
    	host_record = "terraform"
    	type = "A"
    	value = alicloud_instance.myecs.public_ip
    }
    
    
    terraform validate
    terraform plan
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 五、DataSource数据源

    # DataSource
    • datasource提供资源的数据,可以通过参数过滤并供其他模块引用;使用data块声明
    • https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/images
    ......
    data "alicloud_images" "images_ds" {
      owners     = "system"
      name_regex = "^centos_7"
      status = "Available"
      os_type = "linux"
      architecture = "x86_64"
      output_file = "./output.json"
    }
    
    output "first_image_id" {
      value = "${data.alicloud_images.images_ds.images.0.id}"
    }
    ......
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 六、Variable变量

    # Variable
    • 变量允许自定义Terraform模块,而无需更改模块自己的源代码.这可以实现跨不同的Terraform配置共享模块,使用模块可以组合可重用
    variable "access_key" {
      type = string
    }
    
    variable "secret_key" {
      type = string
    }
    
    variable "region" {
      type = string
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    • 在variable.tf文件中定义变量
    • 在同一个模块的所有变量中必须是唯一的
    • 可以从环境变量或者文本文件中读取
    • Terraform默认读取terraform.tfvars`
    # Variable可选参数
    • default变量的默认值
    • type变量的类型
    • description变量的描述信息
    • validation定义变量的验证规则
    • sensitive 限制变量在UI中显示
    • nullable变零是否为空
    variable "region" {
      type = string
      description = "region name"
      default = "cn-shanghai"
      sensitive = true
    }
    
    1
    2
    3
    4
    5
    6
    # Variable参数类型
    • any
    • string
    • number
    • bool
    • list()
    • set()
    • map()
    • object({ATTR_NAME = ATTR_TYPE, ...})
    • tuple([, ...])

    Variable-map-DNS

    • 示例: 使用map类型的变量来定义DNS域名;
    ## variables.tf
    variable "dns_record" {
    	type = map(string)
    	description = "define dns name"
    }
    
    ## terraform.tfvars
    dns_record = {
    	"dev" = "dev.chsaos.com"
    	"stag" = "stag.chsaos.com"
    	"prod" = "prod.chsaos.com"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # Variable-list-ENV
    • 示例:使用list类型的变量来定义环境变量表
    ## variables.tf
    
    variable "env_list" {
    	type = list(string)
    	description = "deploy env name"
    }
    
    ## terraform.tfvars
    env_list = ["dev","stag","prod"]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Variable-object-ECS属性
    • 示例: 使用object类型的变量来定义ECS属性信息
    ## variable.tf
    variable "ecs_info" {
    	type = object({ecs_image = string,ecs_name = string})
    }
    
    ## terraform.tfvars
    ecs_info = {
    	ecs_image = "centos_7_9_x64_20G_alibase_20220824.vhd"
    	ecs_name = "mydemoecs"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # Variable的使用方式

    在变量声明后,可以使用var.VAR_NAME的方式引用;VAR_NAME即variables.tf定义;

    • 环境变量
    • terraform.tfvars | terraform.tfvars.json
    • *.auto.tfvars | *.auto.tfvars.json
    • 命令行 -var | -var-file
    ## alicloud_dns.tf
    
    reource "alicloud_dns_record" "record" {
    	name = "chsaos.com"
    	host_record = var.dns_record["dev"]
    	type = "A"
    	value = "alicloud_instance.myecs.public_ip"
    }
    
    ## -var
    terraform apply -var="region=cn-shanghai"
    terraform apply -var='env_list=["dev","stag"]' -var="region=cn-shanghai"
    
    ## -var-file
    terraform app -var-file="dev.tfvars"
    
    ## env
    export TF_VAR_region = 'cn-shanghai'
    export TF_VAR_env_list = '["dev","stag"]'
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # Variable-locals

    局部、本地变量;局部值有助于避免在配置中多次重复想想的值或表达式

    ## 定义
    locals {
    	ecs_name = "mydemoecs"
    	owner = "chsaos"
    }
    
    ## 引用
    local.ecs_name
    local.owner
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # 七、output输出变量

    # output

    output可以打印已定义的变量,并且可以公开信息以供其他Terraform配置使用.输出值类似于编程语言中的返回值.

    ## output.tf
    output "dev_dns_name" {
    	value = alicloud_dns_record.record.host_record
    }
    
    1
    2
    3
    4
    • 运行 terraform plan

    image-20220914131209520

    # output可选参数
    • description 变量的描述信息
    • sensitive 限制变量在UI中显示
    • depends_on 依赖关系
    # Output-子模块之间的引用

    例如: 如果以一个名为ecs_server的子模块,声明了一个名为instance_ip_addr的输出,则可以将该值作为module.ecs_server.instance_ip_addr.

    module..

    # 八、Module模块

    Terraform可以更轻松地扩展基础架构并保持其配置整洁.但是,随着基础架构的增长,单个目录变得难以管理.

    # Module

    假设: 创建多台服务器? 一遍又一遍重复相同的配置代码?

    ---这就是模块真正有用的地方

    image-20220914132310922

    # Module简介

    terraform模块是一种可重用现有代码的方法,减少基础设施组件开发的代码量.

    Terraform模块是一个或多个.tf文件集合.

    .
    ├── main.tf
    ├── output.tf
    ├── README.md
    └── variables.tf
    
    1
    2
    3
    4
    5

    实际上任何Terraform配置本身已经是一个模块.如果在此目录中运行Terraform,则这些配置文件将被视为根模块

    # Module语法

    name: 模块的名称,在terraform中可以使用模块名称进行引用

    source: 模块代码的路径,本地或者远程的仓库

    version: 版本信息

    参数信息:

    module "name" {
    	source = "xxxx.io/your-org/terraform_test_module"
    	version = "1.0.0"
    	argument_1 = var.test_1
    	argument_2 = var.test_2
    }
    
    1
    2
    3
    4
    5
    6
    # Module项目实践

    项目参考youdianzhishi-terraform/terraform-module-example中的/env/dev

    # Module工作原理

    远程模块: 存储到根模块的.terraform目录中(修改后,必须get/init).

    本地模块: 将通过软连接的方式引用本地的源目录(修改后,无需操作).

    使用terraform get下载模块

    使用terraform graph查看模块; -module-depath汇总对象;

    image-20220914144131006

    # Module调用方式
    本地文件: "./module_name"
    TF注册表: "hashicorp/consul/aws"
    GitHub:
    - http "github.com/hashicorp/example"
    - ssh "git@github.com/hashicop/example.git"
    bucket:
    通用Git:
    - http "git::https://example.com/vpc.git"
    - ssh "git::ssh://username@example.com/storage.git"
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Module-输入、输出变量
    # Child module instance(ECS)
    //main.tf
    resource "alicloud_instance" "myecs" {
    	vswitch_id = var.vsw_id
    	......
    }
    //variables.tf
    variable "vsw_id" {}
    
    
    # Child module network(VPC)
    //main.tf
    resource "alicloud_vpc" "vpc" {
    	......
    }
    
    resource "alicloud_vswitch" "vsw" {
    	vpc_id = alicloud_vpc.vpc.id
    }
    
    //outputs.tf
    output "vsw_id" {
    	value = alicloud_vswitch.vsw.id
    }
    
    
    
    # Root module
    module "dev_ecs" {
    	source = "./moduels/ecs"
    	instance_name = "ecs_01"
    	vsw_id = module.network.vsw_id
    }
    
    module "network" {
    	source = "./module/vpc"
    	...
    }
    
    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
    # Module实例化

    一个模块可以被多次实例化

    每个实例定义唯一的名称,指定相同的source来源;

    module "dev_ecs" {
    	source = "./module/ecs"
    	instance_name = "ecs_01"
    }
    
    module "prod_ecs" {
    	source ="./module/ecs"
    	instance_name = "ecs_02"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Module模块优点
    • 1.解决代码重复问题
    • 2.加强代码读性,代码整洁性
    • 3.资源标准化
    • 4.减少认为错误发生频率

    # 九、Expressions表达式

    # 条件表达式

    condition ? true_val : false_val

    • condition 条件(返回值true/false)
    • true_val 条件为true的值
    • false_val 条件为false的值

    实例仓库: "youdianzhishi-terraform/terraform-expr-demo"

    $ terraform  plan
    
    # consle调试界面
    $ terraform console
    > var.region
    "cn-shanghai"
    > var.region != "" ? var.region : "cn-shanghai"
    "cn-shanghai"
    
    1
    2
    3
    4
    5
    6
    7
    8
    # DEMO

    当region变量存在时region = var.region,反之region = "cn-shanghai"

    var.region != "" ? var.region : "cn-shanghai"
    
    1
    # for表达式

    借助for表达式可以对数据进行处理,生成新的数据对象

    [ for VAR in OBJECT : VAR ]
    [ for INDEX,VAR in OBJECT: "${INDEX}=${VAR}" ]
    
    1
    2
    # 列表遍历(terraform console模式下)
    $  terraform  console
    > [ for value in var.env_name : "${value}"]
    [
      "dev",
      "test",
      "stag",
      "prod",
    ]
    > [ for index,value in var.env_name : "${index}-${value}"]
    [
      "0-dev",
      "1-test",
      "2-stag",
      "3-prod",
    ]
    
    # map遍历(terraform console模式下)
    terraform  console
    >  [ for v in var.dns_record : "${v}" ]
    [
      "dev.app",
      "prod.app",
      "stag.app",
      "test.app",
    ]
    >  [ for k,v in var.dns_record : "${k}:${v}" ]
    [
      "dev:dev.app",
      "prod:prod.app",
      "stag:stag.app",
      "test:test.app",
    ]
    
    
    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
    # splat表达式(动态表达式)

    splat表达式提供了一种简洁的方式来表达可以用for表达式执行的常见操作.

    var.list.*.attr	# 历史书写方式,不推荐
    var.list[*].attr
    
    # terraform console模式下
    $ terraform console
    > var.ecs_spec
    tolist([
      tomap({
        "id" = "100"
        "name" = "ecs01"
        "type" = "ecs.n1.tiny"
      }),
      tomap({
        "id" = "101"
        "name" = "ecs02"
        "type" = "ecs.n1.tiny"
      }),
    ])
    > var.ecs_spec[*].id
    tolist([
      "100",
      "101",
    ])
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    # 十、Functions内置函数

    # 函数

    Terraform语言包括许多内置函数,可以从表达式中调用这些函数来转换.

    函数调用的一般语法是函数名后跟括号以逗号分离的参数.

    function(arg1,arg2)
    
    
    
    # terraform console模式下
    $ terraform console
    > min(1,2,3)
    1
    > max(1,2,3)
    3
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 数值函数
    • max() 获取最大值

    • min() 获取最小值

    • ...将集合扩展为单个参数

    • parseint() 将字符串解析为整数

    max(1,2,3,4,5)
    max([1,2,3,4,5]...)
    min(1,2,3,4,5)
    min([1,2,3,4,5]...)
    parseint("101",10)
    
    > parseint("100",10)  # 转成十进制数
    100
    > parseint("100",2)  # 转成二进制数
    4
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # String字符串函数
    • format() 格式化
    • split() 字符串分割
    • join()字符串拼接
    • replace()替换字符串
    format("Hello %s!","terraform")
    join(",",["name","age","title"])
    replace("a=b=c","=","-")
    split(",","name,age,title")
    
    1
    2
    3
    4
    # Collection集合函数
    函数 功能
    alltrue() anytrue() 判断元素中都是、存在true
    chunklist(list,size) 按照指定size拆分list
    compat(list) 去除list中的空元素
    concat(list1,list2) 合并两个list
    contains(list,value) 判断元素是否存在list中
    distinct(list) 去除list中的重复元素
    element(list,index) list[index] 根据index获取list中的元素
    flatten(list,list,list) 将多层list转换成单list
    index(list,value) 返回value元素的index
    # Map映射函数
    函数 功能
    length(list) 计算map的长度
    lookup(map,key,default) 检索map的key,不存在返回default
    merge(map1,map2,map3) 合并map,相同key会被最后覆盖
    keys(map) values(map) 创建map中key的list 创建map中value的list
    上次更新: 2024/04/09, 16:48:42
    terraform基础
    Backend配置

    ← terraform基础 Backend配置→

    最近更新
    01
    AWS NAT-NetWork-Firwalld配置(一)
    04-09
    02
    AWS NAT-NetWork-Firwalld配置(二)
    04-09
    03
    kubernetes部署minio对象存储
    01-18
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Bruce Tao Blog Space | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式