Not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken

Viewed 427

I'm a newbie to Terraform and I'm trying to deploy a Docker image from AWS ECR to ECS. However, I'm getting the following Error. Can someone help to to resolve this?

ResourceInitializationError: unable to pull secrets or registry auth:
execution resource retrieval failed: unable to retrieve ecr registry
auth: service call has been retried 1 time(s):
AccessDeniedException: User: arn:aws:sts::AccountID:assumed-role/ecsExecution-1/25d077c2af604f4e93feead72a141e3g is not authorized to perform: 
ecr:GetAuthorizationToken on resource: * 
because no identity-based policy allows the 
ecr:GetAuthorizationToken action 
status code: 400, request id: 1a1bee4c-5ab6-4b44-bbf8-5586edea6b3g*

This is my code

resource "aws_ecs_cluster" "first-cluster" {
  name = "test-docker-deploy"
}

resource "aws_ecs_task_definition"  "first-task" {
  family                = "first-task"
  container_definitions = <<TASK_DEFINITION
  [
    {
      "name": "first-task",
      "image": "899696473236.dkr.ecr.us-east-1.amazonaws.com/first-repo:nginx-demo",
      "cpu": 256,
      "memory": 512,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80
        }
      
      ]
    }

  ]
  TASK_DEFINITION
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = 256
  memory                   = 512
  execution_role_arn       = "${aws_iam_role.Execution_Role.arn}"

}

resource "aws_iam_role" "Execution_Role" {
  name                = "ecsExecution-1"
  assume_role_policy  = "${data.aws_iam_policy_document.role_policy.json}"
}

data "aws_iam_policy_document" "role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_ecs_service" "first-service"{
    name                    = "docker-service"
    cluster                 = "${aws_ecs_cluster.first-cluster.id}"
    task_definition         = "${aws_ecs_task_definition.first-task.arn}"
    launch_type             = "FARGATE"
    desired_count           = 1

    network_configuration {
        subnets            = ["${aws_default_subnet.subnet-a.id}"]
        assign_public_ip   = true
    }
}

resource "aws_default_vpc" "default" {
}

resource "aws_default_subnet" "subnet-a" {
  availability_zone = "us-east-1a"
}
1 Answers

Besides having the assume role policy (i.e., permissions or trust policy), you need to have the execution policy [1]. The former one says that ECS task is allowed to assume the role in the background and the latter one says what ECS task can do when it assumes that role. So, the permission policy is correct, but you need the following piece of code for this to work (i.e., the ecs_task_policy):

data "aws_iam_policy_document" "ecs_task_policy" {
  statement {
    sid = "EcsTaskPolicy"

    actions = [
      "ecr:BatchCheckLayerAvailability",
      "ecr:GetDownloadUrlForLayer",
      "ecr:BatchGetImage"
    ]

    resources = [
      "*" # you could limit this to only the ECR repo you want
    ]
  }
  statement {

    actions = [
      "ecr:GetAuthorizationToken"
    ]

    resources = [
      "*"
    ]
  }

  statement {

    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ]

    resources = [
      "*"
    ]
  }

}

resource "aws_iam_role" "Execution_Role" {
  name               = "ecsExecution-1"
  assume_role_policy = data.aws_iam_policy_document.role_policy.json

  inline_policy {
    name   = "EcsTaskExecutionPolicy"
    policy = data.aws_iam_policy_document.ecs_task_policy.json
  }
}

data "aws_iam_policy_document" "role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

Also note that depending on what is inside of the Docker image that you use for the task, it might be required to add more AWS permissions to the execution policy. The ECR repo access can be limited to the ARN of the ECR repo where the Docker image is located. In theory, the log permissions might not be required at this time, but if you want to see if there are any errors you are going to need to send the logs somewhere. If you need that, you will have to add the logConfiguration section to the task definition as well [2].


[1] https://docs.aws.amazon.com/AmazonECS/latest/userguide/task_execution_IAM_role.html

[2] https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html#create_awslogs_loggroups

Related