I'm looking for some advice on best practices managing an AWS Elastic Beanstalk application.
I have an app with 2 different environments which I refer to as prod and dev. I would like to allow deployments to the dev env to all collaborators and limit deployment to prod to only one user.
What is the best way to do that?
ElasticBeanstalk tightly integrates with IAM.
Allowing or Denying a user a specific action on a specific resource can be achieved by attaching the correct policy to the role being assumed.
The ElasticBeanstalk docs have a specific section explaining IAM permissions in EB, and the last example on the page is effectively what you’re looking for. Modify the policy shown to your needs and attach it to the users or groups of users you wish to deny access to the production environment.
Your policy is going to look something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"elasticbeanstalk:CreateApplication",
"elasticbeanstalk:DeleteApplication"
],
"Resource": [
"*"
]
},
{
"Effect": "Deny",
"Action": [
"elasticbeanstalk:CreateApplicationVersion",
"elasticbeanstalk:CreateConfigurationTemplate",
"elasticbeanstalk:CreateEnvironment",
"elasticbeanstalk:DeleteApplicationVersion",
"elasticbeanstalk:DeleteConfigurationTemplate",
"elasticbeanstalk:DeleteEnvironmentConfiguration",
"elasticbeanstalk:DescribeApplicationVersions",
"elasticbeanstalk:DescribeConfigurationOptions",
"elasticbeanstalk:DescribeConfigurationSettings",
"elasticbeanstalk:DescribeEnvironmentResources",
"elasticbeanstalk:DescribeEnvironments",
"elasticbeanstalk:DescribeEvents",
"elasticbeanstalk:DeleteEnvironmentConfiguration",
"elasticbeanstalk:RebuildEnvironment",
"elasticbeanstalk:RequestEnvironmentInfo",
"elasticbeanstalk:RestartAppServer",
"elasticbeanstalk:RetrieveEnvironmentInfo",
"elasticbeanstalk:SwapEnvironmentCNAMEs",
"elasticbeanstalk:TerminateEnvironment",
"elasticbeanstalk:UpdateApplicationVersion",
"elasticbeanstalk:UpdateConfigurationTemplate",
"elasticbeanstalk:UpdateEnvironment",
"elasticbeanstalk:RetrieveEnvironmentInfo",
"elasticbeanstalk:ValidateConfigurationSettings"
],
"Resource": [
"arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/Test/Test-env-prod"
]
}
]
}
The above policy is going to prevent any user with this policy attached from Creating or Deleting any applications, and it's further going to deny the user from completing any of the listed actions on the resource ARN listed; the app named Test and the environment named Test-env-prod.
To restrict access to the specific environment you could use this policy and modify the ARN's region (us-east-1), account-number (123456789012), app-name (Test), and environment-name (Test-env-prod), to your specific needs.
You can find a list of ElasticBeanstalk resource ARN formats here.
Related
I am trying to create an IAM Managed Policy to assign to QA users that will give them readonly access to a specific DBCluster, the QA cluster.
So far I haven't been able to limit the access to the specific cluster, I can only get it to work if the Resource tag is set to all
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"rds:Describe*",
"rds:ListTagsForResource"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "DescribeQADatabase"
}
]
}
I've tried changing the Resource tag to my specific DBCluster ARN, but when I do that nothing shows in the RDS page in the AWS Console
Side question, if I look at the AWS Provided AmazonRDSReadOnlyAccess I see that it gives access to a bunch of other AWS Resources like ec2 instances. Is there a document/resource I can use that will basically tell me all the dependencies I will need if I want to give access to a specific resource?
I'm trying to create some infrastructure for a service I am building on AWS using AWS Fargate. I'm using SSM as a value store for some of my application configuration, so I need both the regular permissions for Fargate as well as additional permissions for SSM. However, after banging my head against this particular wall for a while, I've come to the conclusion that I just don't understand AWS IAM in general or this problem in particular, so I'm here for help.
The basis of my IAM code comes from this tutorial; the IAM code is actually not in that tutorial but rather in this file in the github repo linked to that tutorial. I presume I need to retain that STS permission for something although I'm not entirely sure what.
I've converted the IAM code from the tutorial into a JSON document because I find JSON easier to work with than the Terraform native thing. Here's what I've come up with. It doesn't work. I would like to know why it doesn't work and how to fix it. Please ELI5 (explain like I'm 5 years old) because I know nothing about this.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"secretsmanager:GetSecretValue",
"kms:Decrypt",
"sts:AssumeRole"
],
"Principal": {
"Service": ["ecs-tasks.amazonaws.com"]
}
}
]
}
At a minimum, your ECS task should have below permissions:
Ability to assume a role
Resource level permissions
In the example, you have referred, An IAM Role is created with the following:
A trust relationship is attached. <-- To enable ECS task to assume an IAM role
AWS managed policy AmazonECSTaskExecutionRolePolicy is attached. <-- Resource permissions
So, in order to retrieve the SSM parameter values, add below resource permissions.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:Describe*",
"ssm:Get*",
"ssm:List*"
],
"Resource": [
"arn:aws:ssm:*:*:parameter/{your-path-hierarchy-to-parameter}/*"
]
}
]
}
If your Secrets uses KMS, then grant necessary kms permissions (kms:Decrypt). Refer specifying-sensitive-data for reference.
How to give access to a IAM user to only access resources created by Elastic bean, i.e. The S3 bucket and the EC2 instances. The user should not be able to access any other S3 bucket or EC2 instance not created with Elastic Beanstalk.
The same policy should apply to EC2 instances created automatically via the Auto Scaling policy.
You can go with the "tags" approach. You can set elasticbeanstalk and autoscaling launch configuration to create instances with a predefined "tags" . And you can allow users to see only this tags.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": "*",
"Condition": {"StringEquals": {"ec2:ResourceTag/department": "dev"}}
}
]
}
There could be better approaches, we should wait and see other responses.
best,
What policy templates should an AWS IAM user have in order to deploy and maintain an EB application (e.g. website code from a client machine)? IAMReadOnlyAccess plus PowerUserAccess seem sufficient, but I'm wondering whether the latter is overkill. Can I restrict policies to a single EB instance or application?
When you create an IAM role in the Web Console, there is a pre-defined role called ElasticBeanstalkFullAccess. This will give you full permission to all underlying resources that elastic beanstalk needs. You can see the general doc on this.
Restricting to specific environments or applications is much harder, but doable. It requires you to restrict the user to specific resources using arn's, including all underlying resources and their arn's. See the doc on this.
For reference, the full elastic beanstalk policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticbeanstalk:*",
"ec2:*",
"elasticloadbalancing:*",
"autoscaling:*",
"cloudwatch:*",
"s3:*",
"sns:*",
"cloudformation:*",
"rds:*",
"sqs:*",
"iam:PassRole"
],
"Resource": "*"
}
]
}
I've been testing my continuous deployment setup, trying to get to a minimal set of IAM permissions that will allow my CI IAM group to deploy to my "staging" Elastic Beanstalk environment.
On my latest test, my deployment got stuck. The last event in the console is:
Updating environment staging's configuration settings.
Luckily, the deployment will time out after 30 minutes, so the environment can be deployed to again.
It seems to be a permissions issue, because if I grant s3:* on all resources, the deployment works. It seems that when calling UpdateEnvironment, Elastic Beanstalk does something to S3, but I can't figure out what.
I have tried the following policy to give EB full access to its resource bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/_runtime/_embedded_extensions/APP",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/_runtime/_embedded_extensions/APP/*",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/environments/ENV_ID",
"arn:aws:s3:::elasticbeanstalk-REGION-ACCOUNT/resources/environments/ENV_ID/*"
]
}
]
}
Where REGION, ACCOUNT, APP, and ENV_ID are my AWS region, account number, application name, and environment ID, respectively.
Does anyone have a clue which S3 action and resource EB is trying to access?
Shared this on your blog already, but this might have a broader audience so here it goes:
Following up on this, the ElastiBeanstalk team has provided me with the following answer regarding the S3 permissions:
"[...]Seeing the requirement below, would a slightly locked down version work? I've attached a policy to this case which will grant s3:GetObject on buckets starting with elasticbeanstalk. This is essentially to allow access to all elasticbeanstalk buckets, including the ones that we own. The only thing you'll need to do with our bucket is a GetObject, so this should be enough to do everything you need."
So it seems like ElasticBeanstalk is accessing buckets out of anyone's realm in order to work properly (which is kind of bad, but that's just the way it is).
Coming from this, the following policy will be sufficient for getting things to work with S3:
{
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>",
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>/",
"arn:aws:s3:::elasticbeanstalk-<region>-<account_id>/*"
],
"Effect": "Allow"
},
{
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::elasticbeanstalk*",
"Effect": "Allow"
}
Obviously, you need to wrap this into a proper policy statement that IAM understands. All your previous assumptions about IAM policies have proven right though so I'm guessing this shouldn't be an issue.