利用 AWS s3 存储桶设置 Terraform 后端相对容易。
首先,在您选择的区域(例如 eu-west-1)中创建一个存储桶,命名为 terraform-backend-store(请记住选择一个唯一的名称。)
为此,请打开您的终端并运行以下命令,假设您已正确设置 AWS CLI(否则,请按照official documentation 处的说明进行操作):
aws s3api create-bucket --bucket terraform-backend-store \
--region eu-west-1 \
--create-bucket-configuration \
LocationConstraint=eu-west-1
# Output:
{
"Location": "http://terraform-backend-store.s3.amazonaws.com/"
}
命令应该是不言自明的;要了解更多信息,请查看文档here。
存储桶就位后,需要进行适当的配置以确保安全性和可靠性。
对于保存 Terraform 状态的存储桶,启用服务器端加密是常识。保持简单,首先尝试 AES256 方法(尽管我建议使用 KMS 并实施适当的密钥轮换):
aws s3api put-bucket-encryption \
--bucket terraform-backend-store \
--server-side-encryption-configuration={\"Rules\":[{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}]}
# Output: expect none when the command is executed successfully
接下来,限制对存储桶的访问至关重要;如下创建非特权 IAM 用户:
aws iam create-user --user-name terraform-deployer
# Output:
{
"User": {
"UserName": "terraform-deployer",
"Path": "/",
"CreateDate": "2019-01-27T03:20:41.270Z",
"UserId": "AIDAIOSFODNN7EXAMPLE",
"Arn": "arn:aws:iam::123456789012:user/terraform-deployer"
}
}
记下命令输出中的 Arn(它看起来像:“Arn”:“arn:aws:iam::123456789012:user/terraform-deployer”)。
为了在稍后阶段与 s3 服务和 DynamoDB 正确交互以实施锁定,我们的 IAM 用户必须拥有足够的权限集。
建议对生产环境设置严格的限制,但为了简单起见,开始分配 AmazonS3FullAccess 和 AmazonDynamoDBFullAccess:
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --user-name terraform-deployer
# Output: expect none when the command execution is successful
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess --user-name terraform-deployer
# Output: expect none when the command execution is successful
必须启用新创建的 IAM 用户才能对您的 s3 存储桶执行所需的操作。您可以通过创建和应用正确的策略来做到这一点,如下所示:
cat <<-EOF >> policy.json
{
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/terraform-deployer"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::terraform-remote-store"
}
]
}
EOF
此基本策略文件授予委托人 arn “arn:aws:iam::123456789012:user/terraform-deployer”,以针对具有arn “arn:aws:s3:::terraform-remote-store”。
同样,在生产中需要强制执行更严格的政策。作为参考,请查看AWS Policy Generator。
返回终端并运行如下所示的命令,以在您的存储桶中执行策略:
aws s3api put-bucket-policy --bucket terraform-remote-store --policy file://policy.json
# Output: none
最后一步,启用存储桶的版本控制:
aws s3api put-bucket-versioning --bucket terraform-remote-store --versioning-configuration Status=Enabled
它允许保存不同版本的基础架构状态并轻松回滚到前一阶段而无需费力。
AWS s3 存储桶已准备就绪,是时候将其与 Terraform 集成了。下面列出的是设置此远程后端所需的最低配置:
# terraform.tf
provider "aws" {
region = "${var.aws_region}"
shared_credentials_file = "~/.aws/credentials"
profile = "default"
}
terraform {
backend "s3" {
bucket = "terraform-remote-store"
encrypt = true
key = "terraform.tfstate"
region = "eu-west-1"
}
}
# the rest of your configuration and resources to deploy
一旦到位,必须(再次)初始化 terraform。
terraform init
远程后端准备就绪,测试一下。
锁定呢?
远程存储状态会带来一个陷阱,尤其是在多个任务、工作和团队成员可以访问它的情况下工作时。在这些情况下,多个并发尝试更改状态的风险很高。这里来帮助锁定,该功能可以防止在使用状态文件时打开状态文件。
您可以创建一个 AWS DynamoDB 表来实现锁,terraform 使用它来设置和取消设置锁。
使用 terraform 本身提供资源:
# create-dynamodb-lock-table.tf
resource "aws_dynamodb_table" "dynamodb-terraform-state-lock" {
name = "terraform-state-lock-dynamo"
hash_key = "LockID"
read_capacity = 20
write_capacity = 20
attribute {
name = "LockID"
type = "S"
}
tags {
Name = "DynamoDB Terraform State Lock Table"
}
}
并按如下所示进行部署:
terraform plan -out "planfile" && terraform apply -input=false -auto-approve "planfile"
命令执行完成后,必须将锁定机制添加到您的后端配置中,如下所示:
# terraform.tf
provider "aws" {
region = "${var.aws_region}"
shared_credentials_file = "~/.aws/credentials"
profile = "default"
}
terraform {
backend "s3" {
bucket = "terraform-remote-store"
encrypt = true
key = "terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-state-lock-dynamo"
}
}
# the rest of your configuration and resources to deploy
全部完成。记得再次运行terraform init 并享受您的远程后端。