I'm trying to create a template with cloud formation that sets up a load balancer that writes logs to S3 bucket. Instead of giving full access to everyone (e.g. *), I want to restrict PutObject
access to only the load balancer account or service:
{
"Resources": {
"LoggingBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "LoggingBucket"
},
"PolicyDocument": {
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "LoggingBucket"
},
"/*"
]
]
},
"Principal": {
"Ref": "ElasticLoadBalancingAccountID" //How do I set this dynamically?
}
}
}
}
}
}
The documentation provides account ID's of ELB instances in various regions. However, the template I'm creating has a availability zone parameter where the user can chose a availability zone to deploy the stack to. So what I would ideally like to do is have some sort of ref
variable in my bucket policy that gets the account id of load balancer based on the availability zone.
I also looked at examples in the official documentation, but the one example that does use Ref
, doesn't really define the variable.
How do I achieve this?
Edit: I meant the availability zones instead of region. The input parameter provides the user with a drop down of availability zones in a region.
I figured it out. Its not really dynamic, but better than just hardcoding the id directly. As per this Amazon re-invent presentation, the proper way is to first define a mapping:
{
"Mappings": {
"RegionalConfigs": {
"us-east-1": {
"AMI": "",
"ELBAccountId": "127311923021",
"ArnPrefix": "arn:aws:"
},
"us-west-1": {
"AMI": "",
"ELBAccountId": "027434742980",
"ArnPrefix": "arn:aws:"
},
"us-west-2": {
"AMI": "",
"ELBAccountId": "797873946194",
"ArnPrefix": "arn:aws:"
}
}
}
}
and then use it in a policy:
{
"Resources": {
"LoggingBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"PolicyDocument": {
"Version": "",
"Resource": {
"Fn::Join": [
"",
[
{
"Fn::FindInMap": [
"RegionalConfigs",
{
"Ref": "AWS::Region"
},
"ArnPrefix"
]
},
"s3:::",
{
"Ref": "LoggingBucket"
},
"/",
"Logs",
"/AWSLogs/",
{
"Ref": "AWS::AccountId"
},
"/*"
]
]
},
"Principal": {
"AWS": {
"Fn::FindInMap": [
"RegionalConfigs",
{
"Ref": "AWS::Region"
},
"ELBAccountId"
]
}
},
"Action": [
"s3:PutObject"
]
},
"Bucket": {
"Ref": "LoggingBucket"
}
}
}
}
}
There's no variable that includes the ELB account IDs. Those are AWS's various account identifiers.
To include them in your policy, you have to either:
AWS::Region
variable.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With