通过 Terraform 应用存储桶策略时遇到问题

Having trouble with a applying a bucket policy via Terraform

我曾经有过这个工作,但我可能搞砸了,或者这是一个错误。我认为这可能是一种竞争条件并尝试了一些 depends_on 但仍然没有运气。我似乎无法弄清楚这一点,但我知道 S3 策略对于存储桶和 Terraform 可能具有挑战性。有没有人看出我做错了什么?

resource "aws_s3_bucket_policy" "ct-s3-bucket-policy" {
  bucket = aws_s3_bucket.mylab-s3-bucket-ct.id
  policy = "${data.aws_iam_policy_document.default.json}"
}

resource "aws_cloudtrail" "mylab-cloudtrail" {
  name                          = "mylab-cloudtrail"
  s3_bucket_name                = aws_s3_bucket.mylab-s3-bucket-ct.id
  s3_key_prefix                 = "CT"
  include_global_service_events = true
  event_selector {
    read_write_type = "All"
    include_management_events = true
    data_resource {
      type   = "AWS::S3::Object"
      values = ["arn:aws:s3:::"]
    }
  }
}

resource "aws_s3_bucket" "mylab-s3-bucket-ct" {
  bucket        = "mylab-s3-bucket-ct-1231764516123"
  force_destroy = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
  bucket = aws_s3_bucket.mylab-s3-bucket-ct.id
  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.s3-kms.arn
      sse_algorithm     = "aws:kms"
    }
  }
}
data "aws_iam_policy_document" "default" {
  statement {
    sid    = "AWSCloudTrailAclCheck"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions = [
      "s3:GetBucketAcl",
    ]

    resources = [
      "arn:aws:s3:::${var.cloudtrailbucketname}",
    ]
  }

  statement {
    sid    = "AWSCloudTrailWrite"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions = [
      "s3:PutObject",
    ]

    resources = [
      "arn:aws:s3:::${var.cloudtrailbucketname}/*",
    ]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"

      values = [
        "bucket-owner-full-control",
      ]
    }
  }
}

这是我最后看到的错误。存储桶已创建,但政策不会附加。

    ╷
    │ Error: Error putting S3 policy: MalformedPolicy: Policy has invalid resource
    │       status code: 400, request id: HAK8J85M98TGTHQ4, host id: Qn2mqAJ+oKcFiCD52KfLG+10/binhRn2YUQX6MARTbW4MbV4n+P5neAXg8ikB7itINHOL07DV+I=
    │
    │   with aws_s3_bucket_policy.ct-s3-bucket-policy,
    │   on main.tf line 126, in resource "aws_s3_bucket_policy" "ct-s3-bucket-policy":
    │  126: resource "aws_s3_bucket_policy" "ct-s3-bucket-policy" {
    │
    ╵
    ╷
    │ Error: Error creating CloudTrail: InsufficientS3BucketPolicyException: Incorrect S3 bucket policy is detected for bucket: mylab-s3-bucket-ct-1231764516123
    │
    │   with aws_cloudtrail.mylab-cloudtrail,
    │   on main.tf line 131, in resource "aws_cloudtrail" "mylab-cloudtrail":
    │  131: resource "aws_cloudtrail" "mylab-cloudtrail" {
    │

编辑:为了清楚起见,这只发生在应用中,规划工作正常。

我相信您在存储桶策略和 CloudTrail 跟踪之间存在依赖关系,如下所示:

resource "aws_cloudtrail" "mylab-cloudtrail" {
  name                          = "mylab-cloudtrail"
  s3_bucket_name                = aws_s3_bucket.mylab-s3-bucket-ct.id
  s3_key_prefix                 = "CT"
  include_global_service_events = true
  event_selector {
    read_write_type = "All"
    include_management_events = true
    data_resource {
      type   = "AWS::S3::Object"
      values = ["arn:aws:s3:::"]
    }
  }

  depends_on = [
    aws_s3_bucket_policy.ct-s3-bucket-policy
  ]
}

如果您没有此依赖项,Terraform 将在将必要的策略附加到存储桶之前尝试创建跟踪。

此外,您可能希望在策略中引用存储桶名称并避免使用 var.cloudtrailbucketname:

data "aws_iam_policy_document" "default" {
  statement {
    sid    = "AWSCloudTrailAclCheck"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions = [
      "s3:GetBucketAcl",
    ]

    resources = [
      "arn:aws:s3:::${aws_s3_bucket.mylab-s3-bucket-ct.id}" # Get the bucket name
    ]
  }

  statement {
    sid    = "AWSCloudTrailWrite"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions = [
      "s3:PutObject",
    ]

    resources = [
      "arn:aws:s3:::${aws_s3_bucket.mylab-s3-bucket-ct.id}/*", # Get the bucket name
    ]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"

      values = [
        "bucket-owner-full-control",
      ]
    }
  }
}

原始资源调用

"arn:aws:s3:::${var.cloudtrailbucketname}/*",

改成这个,它起作用了。我引用它而不是构建字符串。无论出于何种原因,JSON 格式不正确。

resources = ["${aws_s3_bucket.mylab-s3-bucket-ct.arn}/*"]

@Erin 帮助我找到了正确的方向