Terraform ELB S3 权限问题
Terraform ELB S3 Permissions Issue
我在使用 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 存储桶来存储日志(它 运行ning 在同一个 AWS 帐户中)。
bucket和ELB都在eu-west-2
.
任何关于问题可能是什么的想法都将不胜感激。
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"
}
}
即使按照文档提供了所有内容,我仍不断收到 "Access Denied for bucket" 错误。从存储桶中删除加密对我有用。
在存储桶策略中,帐号必须不是您的。相反,它属于 AWS,对于每个区域,您应该在存储桶策略中使用的帐号列在:https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy
例如,对于 us-east-1
地区,帐号是 127311923021
。
虽然问题是关于 Terraform 的,但我 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/*"
原则上,使用127311923021
,因为这是AWS帐号,应该用于us-east-1
中的帐号。
存储桶权限
当您启用访问日志记录时,您必须为访问日志指定一个 S3 存储桶。桶必须满足以下要求。
要求
存储桶必须位于与负载均衡器相同的区域中。
需要 Amazon S3 托管加密密钥 (SSE-S3)。不支持其他加密选项。
存储桶必须具有授予 Elastic Load Balancing 将访问日志写入您的存储桶的权限的存储桶策略。存储桶策略是用访问策略语言编写的 JSON 语句的集合,用于定义存储桶的访问权限。每条语句包含关于单个权限的信息,并包含一系列元素。
使用以下选项之一准备用于访问日志记录的 S3 存储桶。
需要 Amazon S3 托管加密密钥 (SSE-S3)。不支持其他加密选项。
所以 AWS 文档说不支持 KMS...
在我的例子中,是 request_payer
选项设置为 Requester
。需要设置为 BucketOwner
才能工作。
我在使用 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 存储桶来存储日志(它 运行ning 在同一个 AWS 帐户中)。
bucket和ELB都在eu-west-2
.
任何关于问题可能是什么的想法都将不胜感激。
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"
}
}
即使按照文档提供了所有内容,我仍不断收到 "Access Denied for bucket" 错误。从存储桶中删除加密对我有用。
在存储桶策略中,帐号必须不是您的。相反,它属于 AWS,对于每个区域,您应该在存储桶策略中使用的帐号列在:https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy
例如,对于 us-east-1
地区,帐号是 127311923021
。
虽然问题是关于 Terraform 的,但我 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/*"
原则上,使用127311923021
,因为这是AWS帐号,应该用于us-east-1
中的帐号。
存储桶权限 当您启用访问日志记录时,您必须为访问日志指定一个 S3 存储桶。桶必须满足以下要求。 要求 存储桶必须位于与负载均衡器相同的区域中。 需要 Amazon S3 托管加密密钥 (SSE-S3)。不支持其他加密选项。 存储桶必须具有授予 Elastic Load Balancing 将访问日志写入您的存储桶的权限的存储桶策略。存储桶策略是用访问策略语言编写的 JSON 语句的集合,用于定义存储桶的访问权限。每条语句包含关于单个权限的信息,并包含一系列元素。
使用以下选项之一准备用于访问日志记录的 S3 存储桶。
需要 Amazon S3 托管加密密钥 (SSE-S3)。不支持其他加密选项。
所以 AWS 文档说不支持 KMS...
在我的例子中,是 request_payer
选项设置为 Requester
。需要设置为 BucketOwner
才能工作。