Terraform尝试在切换到新工作区时再次创建S3后端
我正在遵循极好的地形指南。我目前正在第三篇文章中探索这个州。特别是在演示terraform工作区的位置。 因此,我有以下Terraform尝试在切换到新工作区时再次创建S3后端,terraform,Terraform,我正在遵循极好的地形指南。我目前正在第三篇文章中探索这个州。特别是在演示terraform工作区的位置。 因此,我有以下main.tf: provider "aws" { region = "us-east-2" } resource "aws_s3_bucket" "terraform_state" { bucket = "mark-kharitonov-terraform-up-and-running-state" # Enable versioning so we can
main.tf
:
provider "aws" {
region = "us-east-2"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "mark-kharitonov-terraform-up-and-running-state"
# Enable versioning so we can see the full revision history of our
# state files
versioning {
enabled = true
}
# Enable server-side encryption by default
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-up-and-running-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
terraform {
backend "s3" {
# Replace this with your bucket name!
bucket = "mark-kharitonov-terraform-up-and-running-state"
key = "workspaces-example/terraform.tfstate"
region = "us-east-2"
# Replace this with your DynamoDB table name!
dynamodb_table = "terraform-up-and-running-locks"
encrypt = true
}
}
output "s3_bucket_arn" {
value = aws_s3_bucket.terraform_state.arn
description = "The ARN of the S3 bucket"
}
output "dynamodb_table_name" {
value = aws_dynamodb_table.terraform_locks.name
description = "The name of the DynamoDB table"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
这一切都很棒:
C:\work\terraform [master ≡]> terraform workspace show
default
C:\work\terraform [master ≡]> terraform apply
Acquiring state lock. This may take a few moments...
aws_dynamodb_table.terraform_locks: Refreshing state... [id=terraform-up-and-running-locks]
aws_instance.example: Refreshing state... [id=i-01120238707b3ba8e]
aws_s3_bucket.terraform_state: Refreshing state... [id=mark-kharitonov-terraform-up-and-running-state]
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Releasing state lock. This may take a few moments...
Outputs:
dynamodb_table_name = terraform-up-and-running-locks
s3_bucket_arn = arn:aws:s3:::mark-kharitonov-terraform-up-and-running-state
C:\work\terraform [master ≡]>
现在,我尝试按照指南操作-创建一个新的工作区并在那里应用代码:
C:\work\terraform [master ≡]> terraform workspace new example1
Created and switched to workspace "example1"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
C:\work\terraform [master ≡]> terraform plan
Acquiring state lock. This may take a few moments...
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_dynamodb_table.terraform_locks will be created
+ resource "aws_dynamodb_table" "terraform_locks" {
...
+ name = "terraform-up-and-running-locks"
...
}
# aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0c55b159cbfafe1f0"
...
}
# aws_s3_bucket.terraform_state will be created
+ resource "aws_s3_bucket" "terraform_state" {
...
+ bucket = "mark-kharitonov-terraform-up-and-running-state"
...
}
Plan: 3 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Releasing state lock. This may take a few moments...
C:\work\terraform [master ≡]>
问题就从这里开始。在指南中,terraformplan
命令报告只将创建一个资源—一个EC2实例。这意味着terraform将为后端重用相同的S3 bucket,为锁重用相同的DynamoDB表。但在我的例子中,terraform告诉我它将要创建所有3个资源,包括S3存储桶。这肯定会失败(已经尝试过)
那么,我做错了什么?缺少什么?创建一个新项目实际上是从头开始。在这方面,指导步骤有点混乱,但它们创建了两个计划来实现最终结果。第一个计划创建状态S3 Bucket和锁定DynamoDB表,第二个计划只包含他们正在创建的实例,但使用terraform
代码块告诉该计划将其状态存储在何处
在您的示例中,您正在设置州位置并在同一计划中创建它。这意味着,当您创建一个新工作区时,它将再次尝试创建该状态位置,因为此工作区不知道其他工作区的状态
最后,重要的是要知道,使用工作空间会在每个工作空间中创建唯一的状态文件。例如,如果您的州位置为mark kharitonov terraform up and running state
,路径为workspaces example
,则您可能会看到以下内容:
- 默认状态:
mark kharitonov terraform启动并运行状态/工作区示例/Default/terraform.tfstate
- 其他状态:
mark kharitonov terraform启动并运行状态/工作区示例/Other/terraform.tfstate
- 计划>
- 州>
- main.tf
- 实例>
- main.tf
- 州>
plans/state/main.tf文件中,放置州位置内容:
provider "aws" {
region = "us-east-2"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "mark-kharitonov-terraform-up-and-running-state"
# Enable versioning so we can see the full revision history of our
# state files
versioning {
enabled = true
}
# Enable server-side encryption by default
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-up-and-running-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
output "s3_bucket_arn" {
value = aws_s3_bucket.terraform_state.arn
description = "The ARN of the S3 bucket"
}
然后在plans/instance/main.tf
文件中,您可以使用terraform
块引用创建的状态位置,并且只需要以下内容:
terraform {
backend "s3" {
# Replace this with your bucket name!
bucket = "mark-kharitonov-terraform-up-and-running-state"
key = "workspaces-example/terraform.tfstate"
region = "us-east-2"
# Replace this with your DynamoDB table name!
dynamodb_table = "terraform-up-and-running-locks"
encrypt = true
}
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
该指南解释说,将创建一个唯一的状态文件-terraform会自动更改路径以合并工作区名称。这一部分很清楚。目前尚不清楚的是如何使指南与发生的事情相协调。我该怎么做才能让它工作?这是否意味着我需要将main.tf拆分为两个文件?如何使第二个文件重用相同的S3存储桶。很抱歉,在阅读了你的答案后,我再也没有比以前更接近解决方案了。是的,你需要拆分计划文件。因此,我在开场白中说:“指南步骤在这方面有点混乱,但它们正在制定两个计划以实现最终结果。”。我编辑了我的答案以提供一个例子。重要的是要注意,当您拆分它们时,它们不能在同一个工作目录中,因为terraform apply
和plan
将读取所有.tf
文件。这很有效-谢谢。还有一个问题是,如果我想彻底清理,如何销毁后端状态文件。它们是使用地形应用
创建的,但不会使用地形销毁
删除。正确的做法是什么?还是我单独问一个问题?好问题。它们不会特别伤害任何东西,我也不认为有任何自动删除机制。也许还有一个问题。