I'm trying to follow the steps to use amazon elastic container registry (ECR) but I'm stuck at the first step, which is obtaining an auth token.
Command:
aws ecr get-login
Or...
aws ecr get-login --region=us-west-2
Error:
An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::9#####4:user/### is not authorized to perform: ecr:GetAuthorizationToken on resource: *
AWS Permissions on user for region us-west-2:
AmazonEC2FullAccess
AmazonEC2ContainerRegistryFullAccess
Billing
AdministratorAccess
AmazonECS_FullAccess
AWS CLI version:
aws help --version
aws-cli/1.14.40 Python/3.6.4 Darwin/18.2.0 botocore/1.8.44
Please note that you're not allowing your user any access to ECR in a sense.
Try adding the following policy to the user:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage"
],
"Resource": "*"
}]
}
https://docs.aws.amazon.com/AmazonECR/latest/userguide/ecr_managed_policies.html#AmazonEC2ContainerRegistryReadOnly
As general advice, ecr:GetAuthorizationToken must apparently be applied to all resources * but all other ECR permissions can be scoped. When setting up ECR permissions as below, that user/role can login into Docker via CLI and still only access those images that user/role is supposed to.
Example with scoped permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": "arn:aws:ecr:${region}:${account}:repository/${repo-name}"
},
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}
From my observations, scoping ecr:GetAuthorizationToken to any ECR repositories will result in AccessDeniedException.
Related
I am trying for "IAM permissions for Fargate tasks pulling Amazon ECR images". For that I have used following task execution role policy but getting error called
Error creating IAM Role. MalformedPolicyDocument: Has prohibited field Resource
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:sourceVpce": "vpce-xxxxxx",
"aws:sourceVpc": "vpc-xxxxx"
}
}
}
]
}
Can someone help me with this issue?
I assume you're following this guide?
This is an error that comes up when you try to put an access policy (what a role/user is allowed to do) in a trust policy (who/what is allowed to assume a role).
Essentially, you're trying to put your policy in the wrong spot. The IAM role should specify ECS as the trusted service, and in an attached policy it should have the policy you included in your question.
I'm trying to build a docker image from a Pipeline account and push it into the ECR of another account (Dev).
While I'm able to docker push from codebuild to an ECR repo within the same account (Pipeline), I'm having difficulty doing this for an external AWS account ECR.
The policy attached to the ECR repo on the Dev account:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<pipelineAccountID>:role/service-role/<codebuildRole>"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
}
]
}
On my pipeline account, the service role running the build project matches the ARN on the policy above, and my buildspec contains the following snippet that pushes the image:
- $(aws ecr get-login --no-include-email --region us-east-1 --registry-ids <DevAccount>)
- docker tag <imageName>:latest $ECR_REPO_DEV:latest
- docker push $ECR_REPO_DEV:latest
Codebuild is able to log into ECR successfully, but when it tries to actually push the image, I get:
*denied: User: arn:aws:sts::<pipelineAccountID>:assumed-role/<codebuildRole>/AWSCodeBuild-413cfca0-133a-4f37-b505-a94668201e26 is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:us-east-1:<DevAccount>:repository/<repo>*
Additionally, I've gone ahead and made sure that the IAM policy for role (residing on the codepipeline account) has permissions for this repo:
{
"Sid": "CrossAccountRepo",
"Effect": "Allow",
"Action": "ecr:*",
"Resource": "arn:aws:ecr:us-east-1:<DevAccount>:repository/sg-api"
}
I have little idea now on what I could be missing. The only thing that comes to mind is having the build run with a cross-account role but I'm not even sure that's possible. My goal is to have the build pipeline separate from the dev. account as I hear that's best practice.
Suggestions?
Thanks in advance.
Based on my understanding of this and the error message above, the most common cause is that the ECR repository does not have a policy which would allow the CodeBuild IAM role to access it.
Please set this policy on the ECR Repo:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<dev acount>:root"
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
}
]
}
Ref: https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html#IAM_allow_other_accounts
Please add this policy on the CodeBuild service role:
{
"Sid": "CrossAccountRepo",
"Effect": "Allow",
"Action": "ecr:*",
"Resource": "*"
}
How can I get my ECS Fargate cluster to pull a container from a private Docker registry that is in another AWS account? If the private Docker registry is in the same account I don't need authentication but I get CannotPullContainerError: Error response from daemon: pull access denied for <account id>.dkr.ecr.ap-southeast-2.amazonaws.com/project/container, repository does not exist or may require 'docker login'
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth.html talks about authentication and private registries but doesn't seem to mention my use case of an ECR in another AWS account. It looks like I can add access to a defined list of AWS accounts in the ECR permissions but possibly there are other approaches? The passwords that generated for ECR only seem to last for 12 hours so that won't work.
In the account running your fargate service the task execution role specified in your task definition should have permissions to pull an image.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": "arn:aws:ecr:eu-west-1:<account id>:repository/project",
"Effect": "Allow"
},
{
"Action": "ecr:GetAuthorizationToken",
"Resource": "*",
"Effect": "Allow"
}
]}
And in the account containing the ECR you should specify in ecr policy that the account containing the task execution role is allowed to access the repository. In the ecr policy below the whole account is added which might be a bit much security wise but that something you can tighten.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "PullImage",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<accountid>:root"
},
"Action": [
"ecr:BatchGetImage",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetDownloadUrlForLayer",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:GetRepositoryPolicy",
"ecr:ListImages"
]
}
]
}
I am implementing CodePipeline; using GitHub, CodeBuild and Amazon ECS (blue/green). The role I am using, is the one generated by the Pipeline: ecsTaskExecutionRole
When generated, it is equipped with the following policies:
AmazonECSTaskExecutionRolePolicy (containing the following actions):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]}
And the following Trust relationships:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"codebuild.amazonaws.com",
"ecs-tasks.amazonaws.com",
]
},
"Action": "sts:AssumeRole"
}
]
}
Given that the role is auto-generated, one would assume that either it would have ALL the necessary permissions (for the pipeline to function) OR AWS would have a guide on which permissions to assign (to either a policy OR the trust relationship configuration).
Despite, updating the trust relationship to include:
"Service": [
"codebuild.amazonaws.com",
"ecs-tasks.amazonaws.com",
"ec2.amazonaws.com",
"codedeploy.amazonaws.com",
"codepipeline.amazonaws.com",
"s3.amazonaws.com"
]
I still get the error:
I have seen this issue raised in multiple blogs/forum, spanning the past 1-2 years; it's incredible that this is still not properly documented as part of the AWS tutorials (or relative blogs).
"The provided role does not have sufficient permissions to access CodeDeploy"
This error suggests the CodePipeline role is missing "codedeploy:" related permissions.
Can you please add
codedeploy:*
to the role and try again.
If you do not want to add all CodeDeploy permissions, you will need to investigate 'AccessDenied' calls in Cloudtrail and allow just those. Usually these are the required ones:
{
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetApplication",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:RegisterApplicationRevision"
],
"Resource": "*",
"Effect": "Allow"
},
The default "CodePipeline Service Role Policy" is documented here:
[1] Manage the CodePipeline Service Role - Review the Default CodePipeline Service Role Policy - https://docs.aws.amazon.com/codepipeline/latest/userguide/how-to-custom-role.html#view-default-service-role-policy
Is there a way to give users permission only to push/pull specific Docker images they own in AWS ECS Repo?
By this time you might have the solution, but sharing some info here:
Consider 2 users with the following permissions:
ecr-user with policy ARN: arn:aws:iam::aws:policy/AdministratorAccess who have admin permissions for all resources in AWS:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
vault-user with policy ARN :arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy who has limited permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
You can get this info from IAM->Users and click on the Policy name attached to the user.
Consider below 2 repositories which are associated with users ecr-user and vault-user
the repo ecr-permissions is linked with ecr-user with the following permissions:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "denyAdmin",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::****:user/ecr-user"
},
"Action": [
"ecr:BatchGetImage",
"ecr:DescribeImages",
"ecr:ListImages",
"ecr:PutImage",
"ecr:PutLifecyclePolicy",
"ecr:UploadLayerPart"
]
}
]
}
So with the above policy, you can even restrict admin user(ecr-user) to push to this repo.
$ docker push ****.dkr.ecr.us-east-1.amazonaws.com/ecr-permissions:1.0
The push refers to repository [****.dkr.ecr.us-east-1.amazonaws.com/ecr-permissions]
fe6a7a3b3f27: Layer already exists
d0673244f7d4: Layer already exists
d8a33133e477: Layer already exists
denied: User: arn:aws:iam::****:user/ecr-user is not authorized to perform: ecr:UploadLayerPart on resource: arn:aws:ecr:us-east-1:****:repository/ecr-permissions with an explicit deny
Similarly, you can allow non-admin/user[in this case vault-user] with read-only permission on ECR repo can push docker images by tuning the ECR repo policies as shown below.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "pushDocker",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::****:user/vault-user"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
}
]
}
Before adding the above policy:
$ docker push ****.dkr.ecr.us-east-1.amazonaws.com/rlokinen/first-ecr:0.3
The push refers to repository [****.dkr.ecr.us-east-1.amazonaws.com/rlokinen/first-ecr]
fe6a7a3b3f27: Layer already exists
d0673244f7d4: Layer already exists
d8a33133e477: Layer already exists
denied: User: arn:aws:iam::****:user/vault-user is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:us-east-1:****:repository/rlokinen/first-ecr
after adding the policy:
$ docker push ****.dkr.ecr.us-east-1.amazonaws.com/rlokinen/first-ecr:0.3
The push refers to repository [****.dkr.ecr.us-east-1.amazonaws.com/rlokinen/first-ecr]
fe6a7a3b3f27: Layer already exists
d0673244f7d4: Layer already exists
d8a33133e477: Layer already exists
0.3: digest: sha256:dc85890ba9763fe38b178b337d4ccc802874afe3c02e6c98c304f65b08af958f size: 948
These policies are defined per REPO in ECR. ECR->Repositories-><REPO-NAME>permissions.
You can configure IAM users within your account to push and pull images.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPushPull",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::aws_account_id:user/push-pull-user-1",
"arn:aws:iam::aws_account_id:user/push-pull-user-2"
]
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
}
]
}
Reference: documentation