Skip to content

Instantly share code, notes, and snippets.

@holyjak
Last active June 20, 2022 07:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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": "*"
}
]
}
@kylecordes
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.

@holyjak
Copy link
Author

holyjak commented Sep 1, 2017

Yes :-(

@summera
Copy link

summera commented Sep 5, 2018

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).

Have you found a way to adjust the Policy so that things don't fail when changing files in .ebextensions?

@roshanarvinds
Copy link

@summera, I've tested this on my end and I saw that modifying the policy as below solves the issue :

{
"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-", <---- Modification
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID/
"
]
}
I was able to deploy the ebextensions from my CLI.

@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