Skip to content

Instantly share code, notes, and snippets.

@holyjak
Last active June 20, 2022 07:58
Show Gist options
  • Save holyjak/0055cf69b5b2a9554af67a11828209a5 to your computer and use it in GitHub Desktop.
Save holyjak/0055cf69b5b2a9554af67a11828209a5 to your computer and use it in GitHub Desktop.
IAM policy to allow Continuous Integration user to deploy to AWS Elastic Beanstalk

IAM policy to allow Continuous Integration user to deploy to AWS Elastic Beanstalk

IAM policy that we attach to CI users so that our CI server can deploy new versions of our applications to our EB environments without giving them too many permissions. When some permissions are missing, deploys may fail with the useless and misleading ERROR event log

Service:AmazonCloudFormation, Message:TemplateURL must reference a valid S3 object to which you have access.

(Notice that in many cases the error has nothing to do with S3 but can be caused by any missing permissions, for instance autoscaling:SuspendProcesse. Yes, it sucks.)

The policy can certainly be tightened more, it is not the most restrictive policy that works. As Kyle points out, the full EC2 rights are likely the biggest problem.

What if it fails?

If a deployment to Elastic Beanstalk fails with this policy:

  1. Give the user full access and retry to verify that it as a permission problem.
  2. Revert. You might already have fixed the problem - some deployments need elevated permissions, for example when you change anything in .ebextensions, an elasticbeanstalk.UpdateEnvironment will pass but it will consequently try to UpdateStack, which my fail. But once it succeeds for a given Beanstalk environment, it won't be done again (well, untiil you change the config again).
  3. You are out of luck. AWS is very opaque about what it does and it is hard, if not impossible, to find out what operation failed. CloudTrail does not really help.

Related work

Check out also the popular AWS Elastic Beanstalk deploy user restricted IAM policy by magnetikonline and the comments under it. (Among others, it limits access to only a particular EB application. I am sure I could make my policy more restrictive based on its example.)

Changelog

  • 2017-04-21 Added "s3:Get*","s3:List*", "autoscaling:UpdateAutoScalingGroup", "autoscaling:DescribeLaunchConfigurations" to fix a problem with "Rolling with additional batch" deployments (the infamous "Service:AmazonCloudFormation, Message:TemplateURL must reference a valid S3 object to which you have access.")
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"elasticbeanstalk:CreateApplicationVersion",
"elasticbeanstalk:DescribeEnvironments",
"elasticbeanstalk:DeleteApplicationVersion",
"elasticbeanstalk:UpdateEnvironment"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"sns:CreateTopic",
"sns:GetTopicAttributes",
"sns:ListSubscriptionsByTopic",
"sns:Subscribe"
],
"Effect": "Allow",
"Resource": "arn:aws:sns:REGION:ACCOUNT_ID:*"
},
{
"Action": [
"autoscaling:SuspendProcesses",
"autoscaling:DescribeScalingActivities",
"autoscaling:ResumeProcesses",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:DescribeLaunchConfigurations"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"cloudformation:GetTemplate",
"cloudformation:DescribeStacks",
"cloudformation:CreateStack",
"cloudformation:CancelUpdateStack",
"cloudformation:ListStackResources",
"cloudformation:DescribeStackResource",
"cloudformation:DescribeStackResources",
"cloudformation:DescribeStackEvents",
"cloudformation:DeleteStack",
"cloudformation:UpdateStack"
],
"Effect": "Allow",
"Resource": "arn:aws:cloudformation:REGION:ACCOUNT_ID:*"
},
{
"Action": [
"ec2:DescribeImages",
"ec2:DescribeKeyPairs",
"ec2:describeVpcs",
"ec2:*"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketPolicy",
"s3:Get*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID/*"
]
},
{
"Action": [
"s3:CreateBucket",
"s3:GetObject",
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"elasticloadbalancing:DescribeInstanceHealth",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"autoscaling:DescribeScheduledActions",
"autoscaling:TerminateInstanceInAutoScalingGroup"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
@summera
Copy link

summera commented May 14, 2019

@roshanarvinds thanks for the suggestion! Do you mind posting the full policy? When I made that modification I got a permission denied error on deploy.

@jrichardsz
Copy link

The most problematic bit here is the "ec2:*" - if a machine holding this role was compromised, it could spend unlimited money on EC2 to mine bitcoins or whatever hackers used compromised scalable cloud VMs for nowadays.

Just describe operations are requested, so I think is not to dangerously

@holyjak
Copy link
Author

holyjak commented Jun 20, 2022

Not sure what you mean, @jrichardsz. The actions list various describe operations but it turned out not to be enough and I gave up and and jsut put *, which allows any ec2 operation (so the preceeding lines are superfluous).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment