Using IAM to secure Elastic Beanstalk Applications on AWS

Amazon Web Services provide several ways of making deployment and management of Application and Environments easier, including Elastic Beanstalk which abstracts away the instances, load balancers and auto scaling rules for an environment to allow management and deployment in one place. IAM allows fine grained controls over users and what permissions they are allowed. Combining these two components together should allow you to control what users can do with certain applications, unfortunately as the beanstalk is a layer over other Amazon services it can be a little convoluted to build up the correct rule set for your situation.

Disclaimer: This post talks about security rules and attempting to restrict users access to certain parts of AWS. Remember when reading this post that I’m just some guy on the internet! Check through the rules yourself and try them on a test environment. The information below is given with no warranty or liability, and if you choose to use it, you do so at your own risk. This should be considered a “Works on my cloud” type of post.

The Scenario

We have an Elastic Beanstalk application, and a group of users. This group of users should be able to monitor and deploy to only that elastic beanstalk environment, as well as restarting or terminating application instance. They should not be able to change the application or environments configuration, or delete the environment. The user should not be able to affect other applications or AWS services, but it is acceptable for them to see details on other areas. We assume the user will be using the AWS console.

N.B. – The AWS console doesn’t always take security policies into account until trying to execute an action, this can lead to buttons appearing that the user can’t use, and the user being able to start processes they are unable to finish. The user will not be told until they have pressed it, or even later in an event log.

The Solution

The solution consists of two custom IAM policies. The first handles the rules for the elastic beanstalk and dependent services, the second handles the rules for the EC2 instances.

In both scripts you will need to replace the following values with ones applicable to your environment (Find and replace highly recommended!):

  • 123xxxxxxxxx should be replaced with your Account ID (can be found at the top of your “My Account” page on AWS)
  • ApplicationName should be replaced with the name of your Elastic Beanstalk application
  • If you are not using West Europe region you should replace eu-west-1 with the correct region code, e,g. us-east-1

The policy should allow the user to:

Elastic Beanstalk

For all applications:

  • View and Validate Configuration
  • List types of applications supported
  • Check if an elastic beanstalk DNS name is available
  • Create a storage location (used as part of the application deployment process)

Application Specific

  • View and Update the application
  • View, Create and Update Application Versions
  • View the applications environments
  • View the environments configuration
  • Restart App Servers in an environment
  • Swap CNAMEs between environments
  • Get logs for the environment

Autoscaling

  • View all details, suspend and resume all autoscaling rules

Cloudwatch

  • View all Cloudwatch information

Cloudformation

  • View all Cloudformation information

IAM

  • View the list of all SSL certificates
  • List all IAM Roles

S3

  • See a list of all S3 buckets
  • Access to the bucket used by Elastic Beanstalk for all applications, including Upload and Delete of Objects
  • Access to the Amazon bucket used by Elastic Beanstalk

EC2

  • View all EC2 information

This policy allows the user extra access to the EC2 instances associated with an Environment in the Application, such as restarting and stopping. For this policy you will also need to replace EnvironmentName with the name of your environment, or choose a different Instance tag to filter on, for example if you add a custom tag to all environments when creating your Beanstalk you could use that instead.

 

Please let me know in the comments if you have any suggestions on how to improve these policies! They are not perfect (see the disclaimer at the top of this post!) but work well enough for the scenario I was facing.

Padlock image used is by David Goehring, and is available on Flickr, under a creative commons license.
  • Post
  • Ammar
    Ammar

    Hi Rhys, thanks for the great post. If my worker application accesses Elasticache to set some data periodically, do I also have to provide my IAM worker role permissions to perform operations on my Elasticache node? If yes, then how?

    Your help would be great appreciated!

  • Hi Ammar,

    I've not used elasticache, but it should work in the same way as other AWS resources, you'd need to create the relevant IAM policies for your setup, in a similar way to the policies above. You can see more information of Elasticache IAM policies here: docs.aws.amazon.com/.../UsingIAM.html

    Thanks,

    Rhys

  • Robert
    Robert

    I really appreciate your effort here. I would like to believe that this solves all the problems but i am definitely running into a few but it is likely because i am tightening the security method using some tagging and resource name filters.  This is a great resource (much better than AWS provides in their default policies using "*" everywhere.

  • Thanks Robert, Think this is far from perfect, but hopefully a good starting point! Been in the same position getting frustrated with the AWS documentation on this, really hard to find real world examples!

  • Robert
    Robert

    Homing S3  to your account caused issues..  per AWS.

    ,

            "Effect":"Allow",

            "Resource":[  

               "arn:aws:s3:::elasticbeanstalk-eu-west-1-123xxxxxxxxx",

               "arn:aws:s3:::elasticbeanstalk-eu-west-1-123xxxxxxxxx/*"

            ]

         },

    Try this:

    {

               "Sid": "AllowS3OperationsOnElasticBeanstalkBuckets",

               "Effect": "Allow",

               "Action": [

                   "s3:*"

               ],

               "Resource": [

                   "arn:aws:s3:::elasticbeanstalk-*",

                   "arn:aws:s3:::elasticbeanstalk-*/*"

               ]

           }

    It works.