Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
AWS Elastic Beanstalk deploy user restricted IAM policy.

AWS Elastic Beanstalk deploy user restricted IAM policy

An IAM user policy document to give minimal rights for deploying an Elastic Beanstalk application.

Where:

  • REGION: AWS region.
  • ACCOUNT_ID: AWS account ID.
  • APPLICATION_NAME: Desired target Elastic Beanstalk application name(space).
  • IAM_INSTANCE_PROFILE_ROLE: The instance profile (IAM role) Elastic Beanstalk EC2 instaces will run under.
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"autoscaling:*",
				"cloudformation:*",
				"ec2:*"
			],
			"Effect": "Allow",
			"Resource": [
				"*"
			]
		},
		{
			"Action": [
				"elasticbeanstalk:*"
			],
			"Effect": "Allow",
			"Resource": [
				"arn:aws:elasticbeanstalk:*::solutionstack/*",
				"arn:aws:elasticbeanstalk:REGION:ACCOUNT_ID:application/APPLICATION_NAME",
				"arn:aws:elasticbeanstalk:REGION:ACCOUNT_ID:applicationversion/APPLICATION_NAME/*",
				"arn:aws:elasticbeanstalk:REGION:ACCOUNT_ID:environment/APPLICATION_NAME/*",
				"arn:aws:elasticbeanstalk:REGION:ACCOUNT_ID:template/APPLICATION_NAME/*"
			]
		},
		{
			"Action": [
				"s3:GetObject"
			],
			"Effect": "Allow",
			"Resource": [
				"arn:aws:s3:::elasticbeanstalk-*/*"
			]
		},
		{
			"Action": [
				"s3:CreateBucket",
				"s3:DeleteObject",
				"s3:GetBucketPolicy",
				"s3:GetObjectAcl",
				"s3:ListBucket",
				"s3:PutBucketPolicy",
				"s3:PutObject",
				"s3:PutObjectAcl"
			],
			"Effect": "Allow",
			"Resource": [
				"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID",
				"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID/*"
			]
		},
		{
			"Action": [
				"iam:PassRole"
			],
			"Effect": "Allow",
			"Resource": [
				"arn:aws:iam::ACCOUNT_ID:role/IAM_INSTANCE_PROFILE_ROLE"
			]
		}
	]
}

Notes:

  • The addition of the s3:CreateBucket action against the arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT_ID resource is critical for the creation of new Elastic Beanstalk application instances - even if the bucket itself already exists.
  • Policy has been designed to work with single container Docker environments - not multicontainer, which are ECS cluster environments under the hood and requires additional IAM action permissions.

Reference

Hi,

Thank you for this!

For a reason I ignore, my worker environments required some related SNS permissions:

{
            "Sid": "CreateSnsTopic",
            "Effect": "Allow",
            "Action": [
                "sns:CreateTopic",
                "sns:GetTopicAttributes",
                "sns:ListSubscriptionsByTopic"
            ],
            "Resource": "arn:aws:sns:REGION:ACCOUNT_ID:ElasticBeanstalkNotifications-*"
        }

Not sure why though... Elastic Beanstalk IAM is black magic.

When using this I get the following error: Service:AmazonCloudFormation, Message:TemplateURL must reference a valid S3 object to which you have access.

Which I don't get with the ElasticBeanstalkFullAccess policy, so there is some obscure permission that's missing. Any idea what it might be? It started appearing after I added the .ebextensions folder.

EDIT: Solved it! The key part is that I had to add this:

{
    "Action": [
        "s3:Get*"
    ],
    "Effect": "Allow",
    "Resource": [
        "arn:aws:s3:::elasticbeanstalk-*/*"
    ]
},

It seems like some other Get permission is required and I can't be arsed to find out which one. I also had to add the following since from time to time it would complain about missing these permissions:

{
    "Action": [
        "elasticloadbalancing:DescribeLoadBalancers"
    ],
    "Effect": "Allow",
    "Resource": [
        "*"
    ]
},
{
    "Action": [
        "elasticloadbalancing:RegisterInstancesWithLoadBalancer"
    ],
    "Effect": "Allow",
    "Resource": [
        "arn:aws:elasticloadbalancing:REGION: ACCOUNT_ID:loadbalancer",
        "arn:aws:elasticloadbalancing:REGION: ACCOUNT_ID:loadbalancer/*"
}
    {
        "Action": [
            "autoscaling:*",
            "cloudformation:*",
            "ec2:*"
        ],
        "Effect": "Allow",
        "Resource": [
            "*"
        ]
    }

Is this section too opened?
The User can remove ec2 not created by EB.

Owner

magnetikonline commented Apr 19, 2016

@cnluzhang that's correct - but sadly I have/had been unable to hone in the ARNs better for autoscaling:*, cloudformation:* and ec2:* since they don't really follow any naming scheme/pattern at runtime. If you can improve upon this - would be appreciated!

@magnetikonline @cnluzhang - I'm wondering if the autoscaling, cloudformation, and ec2 permissions could be restricted via the use of tags?

http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html#iam-policy-example-ec2-tag-permissions

As it stands, Elastic Beanstalk already tags resources created as part of an environment, so you could use those, or maybe even adding some custom tags yourself would make this easier.

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.tagging.html

Rob-B1 commented Jul 7, 2016

Yeah you can use tags. I am working on common tenancy with restrictions where they can be done for the ec2 resources.. However Autoscaling isn't as flexible. The EC2 access can be restricted and in anything but dedicated accounts should be.

drrhani commented Jan 27, 2017

Did anyone manage to find a safe and consistently usable policy or approach? We're really struggling with this.

@drrhani I've got nothing for you so far. I've pretty much settled on using Jenkins to handle this, and attaching the ReadOnly policy to my developers along with some Github protected branch black magic.

I have published a policy that works for me, IAM policy to allow Continuous Integration user to deploy to AWS Elastic Beanstalk. In some regards it is more restrictive (e.g. autoscaling), in some less (e.g. not only for a particular application) and it could certainly be tightened more (but life is too short for that :)).

I needed more of S3 permissions to make "Rolling with additional batch" updates working (contrary to "All at once that was already OK) so I added s3:Get*, s3:List*, though I guess that is too permissive.

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