개발하자

Terraform ELBS3 사용 권한 문제

Cuire 2023. 4. 19. 08:26
반응형

Terraform ELBS3 사용 권한 문제

Terraform(v0.9.2)을 사용하여 ELB에 서비스를 추가하는 데 문제가 있습니다(사용 중: ).

실행 시 다음 오류가 발생합니다:

* 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 계정에서 실행 중).

양동이와 ELB가 모두 들어왔습니다.

어떤 문제가 될 수 있는지에 대한 어떤 아이디어도 매우 감사할 것이다.




for ELB 액세스 로그에는 특정 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에서는 다음 문서의 예제에서 볼 수 있듯이 를 사용하여 로그 작성에 사용되는 계정 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"
  }
}



문서 옆에 모든 것이 있을 때도 "버킷에 대한 액세스 거부" 오류가 계속 발생했습니다. 버킷에서 암호화를 제거하는 것이 나에게 효과가 있었다.




버킷 정책에서 계정 번호는 사용자의 것이 아니어야 합니다. 대신 AWS에 속하며 각 지역에 대해 버킷 정책에서 사용해야 하는 계정 번호는 다음에 나열됩니다:

예를 들어 지역의 경우 계정 번호는 입니다.

Terraform에 대한 질문이지만, I post CloudFormation 스니펫은 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/*"

원칙적으로 의 계좌번호는 에서 계좌번호로 사용되어야 하는 AWS 계좌번호입니다.




버킷 권한 액세스 로깅을 사용하도록 설정할 때 액세스 로그에 S3 버킷을 지정해야 합니다. 버킷은 다음 요구 사항을 충족해야 합니다. 요구 사항 버킷은 로드 밸런서와 동일한 영역에 있어야 합니다. Amazon S3 관리 암호화 키(SSE-S3)가 필요합니다. 다른 암호화 옵션은 지원되지 않습니다. 버킷에는 버킷에 액세스 로그를 쓸 수 있는 탄력적인 로드 밸런싱 권한을 부여하는 버킷 정책이 있어야 합니다. 버킷 정책은 버킷에 대한 액세스 권한을 정의하기 위해 액세스 정책 언어로 작성된 JSON 문 모음입니다. 각 문은 단일 권한에 대한 정보를 포함하며 일련의 요소를 포함합니다.

다음 옵션 중 하나를 사용하여 액세스 기록을 위해 S3 버킷을 준비합니다.

Amazon S3 관리 암호화 키(SSE-S3)가 필요합니다. 다른 암호화 옵션은 지원되지 않습니다.

그래서 AWS 문서에는 KMS가 지원되지 않는다고 나와 있습니다...




저 같은 경우에는 옵션 설정이 다음과 같습니다. 작업을 시작해야 합니다.




투표해 주세요. 이것은 완벽한 작동 예입니다.

data "aws_caller_identity" "current" {}
data "aws_elb_service_account" "elb_account_id" {}

resource "aws_s3_bucket" "lb_logs" {
  bucket = "${local.name}-loadbalancer-logs"
}

resource "aws_s3_bucket_policy" "lb_logs" {
  bucket = aws_s3_bucket.lb_logs.id
  policy = data.aws_iam_policy_document.allow_lb.json
}

data "aws_iam_policy_document" "allow_lb" {
  statement {
    effect = "Allow"
    resources = [
      "arn:aws:s3:::${aws_s3_bucket.lb_logs.bucket}/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
    ]
    actions = ["s3:PutObject"]
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${data.aws_elb_service_account.elb_account_id.id}:root"]
    }
  }

  statement {
    effect = "Allow"
    resources = [
      "arn:aws:s3:::${aws_s3_bucket.lb_logs.bucket}/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
    ]
    actions = ["s3:PutObject"]
    principals {
      type        = "Service"
      identifiers = ["delivery.logs.amazonaws.com"]
    }
    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
  }

  statement {
    effect = "Allow"
    resources = [
      "arn:aws:s3:::${aws_s3_bucket.lb_logs.bucket}",
    ]
    actions = ["s3:GetBucketAcl"]
    principals {
      type        = "Service"
      identifiers = ["delivery.logs.amazonaws.com"]
    }
  }
}

resource "aws_alb" "lb" {
  name               = "${local.name}-lb"
  load_balancer_type = "application"
  subnets            = var.subnet_ids
  security_groups    = [
    aws_security_group.lb.id
  ]

  access_logs {
    bucket  = aws_s3_bucket.lb_logs.id
    enabled = true
  }

  lifecycle {
    create_before_destroy = true
  }

  tags = {
    Name = "${local.name}-lb"
  }
}

반응형