Terraform入门


最重要的东西放最前面,多看官方文档:Terraform Tutorials - HashiCorp Learn

1. Terraform是什么?

Terraform是一种开源工具,用于安全高效地预览、配置和管理云基础架构和资源。HashiCorp Terraform是一个IT基础架构自动化编排工具,可以用代码来管理维护IT资源。它编写了描述云资源拓扑的配置文件中的基础结构,例如虚拟机、存储账户和网络接口。Terraform的命令行接口(Command Line Interface,CLI)提供一种简单机制,用于将配置文件部署到阿里云或其他任意支持的云上,并对其进行版本控制。

更多信息,请参见 HashiCorp Terraform

2. Terraform能干什么?

  • 它可以用来构建和准备基础架构(VPC,子网,安全组,虚拟机等)
  • 它不是管理应用程序的工具(如果要管理应用程序,我们可以使用Ansible, Chef, Puppets, and Salt Stack等)
  • 它可以用来创建虚拟server (eg. EC2 实例)以及所有的虚拟网络组件(VPC,子网,安全组),甚至可以执行bash脚本在server上安装基本软件包
  • 虽然可以用它来调用配置管理工具(像Ansible脚本),但这会显得很笨重复杂

3. Terraform的优点?

  • 支持多种云平台(AWS云,azure云,谷歌云等)
  • 配置比较容易理解(human readable)
  • 可以追踪资源的状态
  • 文本描述的配置,方便引入版本管理,从而协同开发

4. 安装Terraform

4.1. 配置本地连接云端的CLI工具

一般来说,操作AWS云,需要安装 AWS CLI, 然后配置环境变量:

export AWS_ACCESS_KEY_ID="<YOUR_AWS_ACCESS_KEY_ID>"
export AWS_SECRET_ACCESS_KEY="<YOUR_AWS_SECRET_ACCESS_KEY>"
export AWS_DEFAULT_REGION="<YOUR_AWS_DEFAULT_REGION>"

4.2. 安装Terraform

对于Ubuntu来说,执行以下脚本即可。

# https://www.terraform.io/downloads
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform

查看版本:terraform -v(当前安装的版本是: v1.1.8)

5. 使用Terraform

5.1. 一般流程

官网提供了很好的示例教程,跟着操作即可。

5.2. 命令总结

命令 作用
terraform init 初始化一个文件夹,准备操作云端(provider)的配置、工具、插件
terraform validate 验证脚本是否有语法错误
terraform apply 创建资源 【幂等的操作】,跟上参数:-auto-approve 就不会要求输入yes确认
terraform show 查看资源状态(eg. EC2实例的ip地址,各种属性)
terraform state list 显示创建的资源列表
terraform destroy 销毁所有创建的资源
terraform output 显示输出的变量列表
terraform graph provide a visual representation of all your infrastructure.
terraform plan 显示当前工程即将创建的资源,用于apply之前确认下

※ 对于terraform graph命令生成的文件,可以用工具:blast-radius --serve 来查看

5.3. 脚本名称总结

名称 作用
main.tf 定义各种资源,也可以包含provider
provider.tf 定义provider
backend.tf Configuration of the backend at Terraform Cloud
terraform.tfstate 记录当前状态, apply时会比较状态
tfstate.backup 备份,非常重要

5.4. 脚本示例

  1. 定义provider
provider "aws" {
region = "us-east-1" # region是保留字
shared_credentials_file = ".aws/credentials" # 这个似乎可以不加,默认的行为
}

目前支持的Provider - 云平台列表: Browse Providers | Terraform Registry 【常见的有AWS,阿里云,Azure云等】

  1. 描述资源的格式
# 1. provider_specific: 各个云平台提供的资源名称,是固定的【云平台】
# 2. a_given_name: 这个是用户起的资源的名称
resource "provider_specific" "a_given_name" {
# 3. 定义资源的属性列表,每类资源需要定义的属性不一样【云平台】
attributes specific to the resource go here.
}
# 举例,创建一个aws实例
resource "aws_instance" "my_ec2_server" {
ami = "ami-02e136e904f3da870"
instance_type = "t2.micro"

tags = {
Name = var.instance_name
}
}
  1. 创建常用的AWS资源
# 创建 vpc
resource "aws_vpc" "demo_vpc_name" {
cidr_block = "10.10.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = { Name = "demo_vpc_name" }
}
# 创建 Internet Gateway
resource "aws_internet_gateway" "demo-igw-name" {
vpc_id = aws_vpc.demo_vpc_name.id
tags = { Name = "demo-igw-name" }
}
# public routing table
resource "aws_route_table" "public-rt" {
vpc_id = aws_vpc.demo_vpc_name.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.demo-igw-name.id
}
tags = { Name = "public access routing table" }
}
# 创建 public subnet
resource "aws_subnet" "public-subnet" {
vpc_id = aws_vpc.demo_vpc_name.id
cidr_block = "10.10.1.0/24"
map_public_ip_on_launch = true
availability_zone = "us-east-1a"
tags = { Name = "public-subnet" }
}
# 创建 private subnet
resource "aws_subnet" "private-subnet" {
vpc_id = aws_vpc.demo_vpc_name.id
cidr_block = "10.10.2.0/24"
availability_zone = "us-east-1b"
tags = { Name = "private-subnet" }
}

# 关联public subnet 和 public route table
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public-subnet.id
route_table_id = aws_route_table.public-rt.id
}

# 创建安全组
resource "aws_security_group" "my-sg" {
name = "my-sg"
description = "allow ssh and web"
vpc_id = aws_vpc.demo_vpc_name.id
ingress {
description = "Allow SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Allow HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
description = "Allow all traffic"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

# 创建一个公有子网的EC2实例
resource "aws_instance" "MyVMInstance" {
ami = "ami-047a51fa27710816e"
instance_type = "t2.micro"
subnet_id = aws_subnet.public-subnet.id
availability_zone = "us-east-1a"
security_groups = [aws_security_group.my-sg.id]
key_name = "demo" # 这个必须提前在aws上配置好,不存在会报错
tags = { Name = "VM-01" }
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install httpd -y
cd /var/www/html
echo "VM $(hostname -f)" > index.html
systemctl restart httpd
systemctl enable httpd
EOF
}

6. Terraform总结

  1. terraform apply 是幂等的操作,不论执行多少次,资源的状态都是一致的(它会比较当前记录的资源状态)
  2. terraform 脚本使用的语法是HCL,所以在VS Code中,可以安装对应的语法高亮插件和关键字自动补全
  3. terraform init初始化后,provider会保存在文件夹下面:.terraform/providers/registry.terraform.io/hashicorp
  4. 可以多用terraform validate 来检测是否有语法错误
  5. 可以多用terraform plan 来查看即将要创建的资源有哪些
  6. HCL 语法里,是大小写敏感的,并且字符串使用的是双引号,不能用单引号。注释是用#开头
  7. terraform 变量的优先级:它有5个优先级,1-最高,5-最低
    1. Command line flag - run as a command line switch
    2. Configuration file - set in your terraform.tfvars file
    3. Environment variable - part of your shell environment
    4. Default Config - default value in variables.tf
    5. User manual entry - if not specified, prompt the user for entry

6.1. 比较好的参考资源

  1. 资源编排 TIC 概述 - Terraform 指南 - 文档中心 - 腾讯云

文章作者: IT神助攻
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 IT神助攻 !
  目录