第一次使用Terraform
第一次使用Terraform
背景 – 背景资料
在工作中,我被指派使用Terraform。尽管我以前没有使用过CloudFormation,有点困惑。但这是一个很好的机会来实践基础设施即代码(IaC)。在开始处理工作之前,我先进行预习一下。
设定
使用Terraform在AWS上搭建EC2实例。
环境
以前一直使用的aws-cli现在可以在Docker容器中安装Terraform,并从Docker容器中运行。
请参阅
・安装Terraform
・用10分钟理解Terraform
・在AWS上初步了解Terraform
文件架构
terraform
└terraform.tfvars
└variables.tf
└ec2.tf
修改基础设施
└terraform.tfvars
└variables.tf
└ec2.tf
步骤
构建环境
我在Dockerfile中添加了以下内容,并重新构建了容器。
# install terraform
RUN apt-get update && apt-get install -y gnupg software-properties-common curl
RUN curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
RUN apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
RUN apt-get update && apt-get install terraform
terraform.tfvars是用于定义变量的文件。
在每个定义文件中直接记录变量也是一种方法,但为了增加通用性,我选择将变量放在外部。
如果在名为”terraform.tfvars”的文件中定义变量,terraform在执行时会自动读取它们。
这次,我定义了连接AWS所需的访问密钥和秘密密钥。
aws_access_key = "xxxxxxxxxx"
aws_secret_key = "xxxxxxxxxx"
请将环境设置文件 “variables.tf” 用中文原生方式改述。
根据这个文件中的描述,看起来是关于连接环境的信息。有些网站是用一个名为”main.tf”的文件创建的。
这一次,我们已经将访问密钥和秘密密钥从单独的文件中定义的变量中读取出来。
尽管我也可以不使用区域,但为了确认变量定义的变化,我在该文件的开头定义了变量,然后尝试了从变量读取值的使用方法,例如访问密钥和密钥等。
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
default = "us-west-2"
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.region}"
}
用于创建EC2实例的定义文件”ec2.tf”。
为了尝试运行,我打算构建一个看起来简单的EC2实例。
我会尝试使用Ubuntu 20.04来使用一个AMI。我将使用1个t2.micro大小进行构建。
resource "aws_instance" "xxxxxxxxxx_tf-ec2" {
count = 1
ami = "ami-03d5c68bab01f3496" # Ubuntu 20.04 LTS official ami
instance_type = "t2.micro"
tags = {
Name = "${format("xxxxxxxxxx_tf-ec2-%02d", count.index + 1)}"
}
}
terraform的初始设置
在存储上述文件的文件夹中执行初始设置命令。
执行此命令将使得terraform能够识别使用的文件。
它与在使用git命令之前执行的“git init”非常相似。
# terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v2.70.0
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
日志输出设置
经过查证,似乎为了确认日志,最好在执行前进行以下设置。
$ export TF_LOG=1
$ export TF_LOG_PATH='./terraform.log'
似乎在执行「terraform apply」后,可以通过「cat terraform.log」命令查看日志。
在执行 Terraform 之前预先确认执行计划。
在实际构建之前,似乎可以确认构建的内容是什么。
请仔细查看这里输出的结果,确认它是否符合预期。
这些信息似乎可以用作构建前的审查材料。
# terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.xxxxxxxxxx_tf-ec2[0] will be created
+ resource "aws_instance" "xxxxxxxxxx_tf-ec2" {
:
:
:
Plan: 1 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.
在terraform中实际尝试构建
确认内容后,将尝试进行实际构建。会输出类似执行计划时的信息,但最后会询问是否允许构建,然后输入”yes”并按下回车键。
# terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.xxxxxxxxxx_tf-ec2[0] will be created
+ resource "aws_instance" "xxxxxxxxxx_tf-ec2" {
:
:
:
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.xxxxxxxxxx_tf-ec2[0]: Creating...
aws_instance.xxxxxxxxxx_tf-ec2[0]: Still creating... [10s elapsed]
:
:
:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
确认terraform执行结果
似乎可以通过命令来确认执行结果。
# terraform show
# aws_instance.xxxxxxxxxx_tf-ec2[0]:
resource "aws_instance" "xxxxxxxxxx_tf-ec2" {
ami = "ami-03d5c68bab01f3496"
arn = "arn:aws:ec2:us-west-2:854542366722:instance/i-0e75162145dc7f328"
associate_public_ip_address = true
availability_zone = "us-west-2a"
为了确认起见,可以尝试在AWS管理控制台上查看一下。
我已经使用命令确认过了,但为了确保起见,我会登录管理控制台再次确认一下。
看起来确实已经成功构建了。
使用Terraform删除已构建的环境
这次的目的是尝试构建,并为了削减成本而删除了已构建的环境。
尽管这次我们使用了Destroy命令进行了批量删除,但是否可以单独删除还需要另行调查。
# terraform destroy
aws_instance.xxxxxxxxxx_tf-ec2[0]: Refreshing state... [id=i-0e75162145dc7f328]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
- destroy
Terraform will perform the following actions:
# aws_instance.xxxxxxxxxx_tf-ec2[0] will be destroyed
- resource "aws_instance" "xxxxxxxxxx_tf-ec2" {
:
:
:
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.xxxxxxxxxx_tf-ec2[0]: Destroying... [id=i-0e75162145dc7f328]
aws_instance.xxxxxxxxxx_tf-ec2[0]: Still destroying... [id=i-0e75162145dc7f328, 10s elapsed]
aws_instance.xxxxxxxxxx_tf-ec2[0]: Still destroying... [id=i-0e75162145dc7f328, 20s elapsed]
:
:
:
Destroy complete! Resources: 1 destroyed.
为了确认起见,我会在AWS管理控制台上进行检查。
当然的结果,但实例已正确删除。
最后
这一次只是构建了一个非常简单的EC2实例,但通过接触IaC,我们能够实现一部分。
Terraform的模板文件在这里也是公开的,所以只要根据自己想要构建的环境修改值并执行,就可以构建环境。
我认为最好将指定的信息变量化,而不是直接在模板中编写,并提高通用性。
文档概述 | hashicorp/aws | Terraform 注册表
我目前有一个本地文件,但我希望能够将其注册到GitLab等平台上,然后从那里克隆并执行。如果可能的话,我也想创建这样一个环境。