锁定 Terraform 状态文件不被覆盖的方法

Way to lock Terraform state file from being overwritten

我们有一个共享的 terraform 状态文件,其中包含有关 VPC id、子网 id 等的信息,这是存储在 Amazon S3 存储桶中的共享状态。我们使用状态信息来启动 AWS 中的各个集群。除管理员外,任何人都不应该覆盖初始地形文件,有没有办法锁定 s3 中的状态,所以没有对现有状态进行 changes/modification ?这可行吗?或者有什么办法解决!谢谢

Terraform 本身无法控制对 S3 中状态快照的访问,但您可以使用 S3 bucket IAM policies 来控制允许对整个 S3 存储桶或 S3 存储桶中的特定路径执行哪些操作,使用IAM 用户和角色。

Amazon 指南中有更多信息 Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket

在您的情况下,我认为您会有两组策略声明,每组都与一组不同的 IAM 主体(用户或角色)相关联。第一个将向您的管理员授予写入权限,这可能类似于控制台访问指南中的示例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListAllMyBuckets"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::bucketname"]
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": ["arn:aws:s3:::bucketname/stateobject.tfstate"]
    }
  ]
}

第二个是向需要它的人授予读取权限,这与上面的非常相似,但会排除 s3:PutObjects3:DeleteObject 操作,以便仅关联主体具有读取权限。

S3 不支持锁定对象。相反,我们可以通过单独作为另一个 terraform 项目来最小化共享状态文件的更改。

在这种情况下,可以通过 remote state 引用新的 Terraform 堆栈。作为普通用户,他们只需要在申请时拥有 s3://terraform-state-prod/network/terraform.tfstate 的读取权限。

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "terraform-state-prod"
    key    = "network/terraform.tfstate"
    region = "us-east-1"
  }
}

resource "aws_instance" "foo" {
  # ...
  subnet_id = data.terraform_remote_state.network.outputs.subnet_id
}