【问题标题】:Terraform ELB S3 Permissions IssueTerraform ELB S3 权限问题
【发布时间】:2017-09-08 00:40:02
【问题描述】:

我在使用 Terraform (v0.9.2) 向 ELB 添加服务时遇到问题(我正在使用:https://github.com/segmentio/stack/blob/master/s3-logs/main.tf)。

当我运行 terraform apply 时,我收到此错误:

* module.solr.module.elb.aws_elb.main: 1 error(s) occurred:

* aws_elb.main: Failure configuring ELB attributes: 
    InvalidConfigurationRequest: Access Denied for bucket: my-service-
    logs. Please check S3bucket permission
    status code: 409, request id: xxxxxxxxxx-xxxx-xxxx-xxxxxxxxx

我的服务如下所示:

module "solr" {
  source = "github.com/segmentio/stack/service"
  name = "${var.prefix}-${terraform.env}-solr"
  environment = "${terraform.env}"
  image = "123456789876.dkr.ecr.eu-west-2.amazonaws.com/my-docker-image"
  subnet_ids = "${element(split(",", module.vpc_subnets.private_subnets_id), 3)}"
  security_groups = "${module.security.apache_solr_group}"
  port = "8983"
  cluster = "${module.ecs-cluster.name}"
  log_bucket = "${module.s3_logs.id}"

  iam_role = "${aws_iam_instance_profile.ecs.id}"
  dns_name = ""
  zone_id = "${var.route53_zone_id}"
}

我的 s3-logs 存储桶如下所示:

module "s3_logs" {
  source = "github.com/segmentio/stack/s3-logs"
  name = "${var.prefix}"
  environment = "${terraform.env}"
  account_id = "123456789876"
}

我签入了 S3,存储桶策略如下所示:

{
  "Version": "2012-10-17",
  "Id": "log-bucket-policy",
  "Statement": [
  {
  "Sid": "log-bucket-policy",
  "Effect": "Allow",
  "Principal": {
  "AWS": "arn:aws:iam::123456789876:root"
  },
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::my-service-logs/*"
  }
  ]
}

据我所知,ELB 应该可以访问 S3 存储桶来存储日志(它在同一个 AWS 账户中运行)。

bucket和ELB都在eu-west-2

任何关于问题可能是什么的想法都将不胜感激。

【问题讨论】:

    标签: amazon-web-services amazon-s3 terraform elastic-load-balancer


    【解决方案1】:

    ELB 访问日志的 docs 表示您希望允许特定的 Amazon 账户能够写入 S3,而不是您的账户。

    因此你想要这样的东西:

    {
      "Id": "Policy1429136655940",
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "Stmt1429136633762",
          "Action": [
            "s3:PutObject"
          ],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::my-loadbalancer-logs/my-app/AWSLogs/123456789012/*",
          "Principal": {
            "AWS": [
              "652711504416"
            ]
          }
        }
      ]
    }
    

    在 Terraform 中,您可以使用 aws_elb_service_account data source 自动获取用于写入日志的帐户 ID,如文档中的示例所示:

    data "aws_elb_service_account" "main" {}
    
    resource "aws_s3_bucket" "elb_logs" {
      bucket = "my-elb-tf-test-bucket"
      acl    = "private"
    
      policy = <<POLICY
    {
      "Id": "Policy",
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "s3:PutObject"
          ],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::my-elb-tf-test-bucket/AWSLogs/*",
          "Principal": {
            "AWS": [
              "${data.aws_elb_service_account.main.arn}"
            ]
          }
        }
      ]
    }
    POLICY
    }
    
    resource "aws_elb" "bar" {
      name               = "my-foobar-terraform-elb"
      availability_zones = ["us-west-2a"]
    
      access_logs {
        bucket   = "${aws_s3_bucket.elb_logs.bucket}"
        interval = 5
      }
    
      listener {
        instance_port     = 8000
        instance_protocol = "http"
        lb_port           = 80
        lb_protocol       = "http"
      }
    }
    

    【讨论】:

    • 在政策中正确使用Resource 对我来说是解决问题的方法。文档要求类似"arn:aws:s3:::my-loadbalancer-logs/my-app/AWSLogs/123456789012/*". Leaving off the account id at the end worked (e.g. "arn:aws:s3:::my-loadbalancer-logs/my-app/AWSLogs/*"`)
    【解决方案2】:

    即使拥有文档中的所有内容,我仍然不断收到“拒绝访问存储桶”错误。从存储桶中删除加密对我有用。

    【讨论】:

    • 谢谢,为我解决了这个问题。您是否找到了一种方法来修改政策,从而不再需要这样做?
    • 不,我停止尝试,因为这对我的情况并不重要。很想听听是否有人找到了实现这项工作的方法。
    【解决方案3】:

    在存储桶策略中,帐号必须不是您的。相反,它属于 AWS,对于每个区域,您应该在存储桶策略中使用的帐号列在:https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy

    例如,对于us-east-1 区域,帐号是127311923021

    虽然问题是关于 Terraform,但我发布了 CloudFormation sn-p 为 ELB 的访问日志创建了一个存储桶其存储桶策略:

        MyAccessLogsBucket:
            Type: AWS::S3::Bucket
            DeletionPolicy: Retain
    
    
        MyAllowELBAccessBucketPolicy:
            Type: AWS::S3::BucketPolicy
            Properties: 
                Bucket: !Ref MyAccessLogsBucket
                PolicyDocument: 
                    Version: "2012-10-17"
                    Statement: 
                        - Effect: "Allow"
                          Principal: 
                              AWS: "arn:aws:iam::127311923021:root"
                          Action: 
                              - "s3:PutObject"
                          Resource: !Sub "arn:aws:s3:::${MyAccessLogsBucket}/AWSLogs/*"
    
    

    原则上使用127311923021,因为这是AWS账号,us-east-1中的账号应该使用。

    【讨论】:

      【解决方案4】:

      存储桶权限 当您启用访问日志时,您必须为访问日志指定一个 S3 存储桶。桶必须满足以下要求。 要求 存储桶必须与负载均衡器位于同一区域。 需要 Amazon S3 托管的加密密钥 (SSE-S3)。不支持其他加密选项。 存储桶必须具有授予 Elastic Load Balancing 将访问日志写入您的存储桶的权限的存储桶策略。存储桶策略是使用访问策略语言编写的 JSON 语句的集合,用于定义存储桶的访问权限。每个语句都包含有关单个权限的信息并包含一系列元素。

      使用以下选项之一准备 S3 存储桶以进行访问日志记录。

      需要 Amazon S3 托管的加密密钥 (SSE-S3)。不支持其他加密选项。

      所以 AWS 文档说不支持 KMS...

      【讨论】:

        【解决方案5】:

        在我的例子中,request_payer 选项设置为Requester。需要设置为BucketOwner 才能工作。

        【讨论】:

          猜你喜欢
          • 2018-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          • 1970-01-01
          • 1970-01-01
          • 2019-06-25
          • 2011-11-17
          相关资源
          最近更新 更多