Skip to content

(aws-codepipeline-actions): TagParameterContainerImage unusable cross-account #15070

@danwiltshire

Description

@danwiltshire
Contributor

Using TagParameterContainerImage as a property for a stack in a different account causes a resolution error.

Reproduction Steps

const myPipeline = new MyPipeline(app, 'my-pipeline', {
  env: nonprod
}

new MyFargateApp(app, 'my-app', {
  env: prod
  image: myPipeline.tagParameterContainerImage
}

What did you expect to happen?

Stack my-app should reference the ECR repo from my-pipeline.

What actually happened?

Error: Resolution error: Resolution error: Resolution error: Resolution error: Resolution error: Cannot use resource 'my-app/FargateService/TaskDef/ExecutionRole' in a cross-environment fashion, the resource's physical name must be explicit set or use 'PhysicalName.GENERATE_IF_NEEDED'.

Environment

  • CDK CLI Version : 1.107.0 (build 52c4434)
  • Framework Version: 1.107.0
  • Node.js Version: 14.16.0
  • OS : WSL2 Ubuntu 20.04.02 LTS on Windows 10 1909
  • Language (Version): TypeScript (3.9.9)

Other details

I'm using ApplicationLoadBalancedFargateService.

This is 🐛 Bug Report

Activity

added
bugThis issue is a bug.
needs-triageThis issue or PR still needs to be triaged.
on Jun 10, 2021
skinny85

skinny85 commented on Jun 10, 2021

@skinny85
Contributor

Thanks for reporting @danwiltshire. Confirming I was able to reproduce it. I'm working on a fix.

In the meantime, you should be able to unblock yourself by passing the executionRole of the TaskDefinition explicitly with a Role that has the name set, like so:

      const fargateTaskDefinition = new ecs.FargateTaskDefinition(this, 'ServiceTaskDefinition', {
        executionRole: new iam.Role(serviceStack, 'ExecutionRole', {
          assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
          roleName: 'my-name',
        }),
      });

If you don't want to set a name yourself, you can pass roleName as cdk.PhysicalName.GENERATE_IF_NEEDED, and the CDK will generate it for you automatically.

added
effort/smallSmall work item – less than a day of effort
and removed
needs-triageThis issue or PR still needs to be triaged.
on Jun 10, 2021
added a commit that references this issue on Jun 10, 2021
17e9945
danwiltshire

danwiltshire commented on Jun 11, 2021

@danwiltshire
ContributorAuthor

Hey @skinny85 thanks, this got me a bit further. I'm now getting another issue where the ECR policy principal is not valid.

Error: Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided'

Cause: The Principal field must contain an asterisk when a full role ARN is used.

Solutions:

  • Use an asterisk in the ARN
  • Use the AWS root reference (as shown in Working policy below).

Synthed CFN:

    "FargatePipelineEcsDeployRepository70287658": {
      "Type": "AWS::ECR::Repository",
      "Properties": {
        "RepositoryName": "<EXPLICIT_REPO_NAME>",
        "RepositoryPolicyText": {
          "Statement": [
            {
              "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage"
              ],
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      {
                        "Ref": "AWS::Partition"
                      },
                      ":iam::<ACCOUNT_NUMBER>:role/prod-appappexecutionrole0e3f44e5e1548be0860e"
                    ]
                  ]
                }
              }
            }
          ],
          "Version": "2012-10-17"
        },
      },
      "UpdateReplacePolicy": "Retain",
      "DeletionPolicy": "Retain",
      "Metadata": {
        "aws:cdk:path": ".../FargatePipeline/EcsDeployRepository/Resource"
      }
    },

Working policy:

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "new statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ACCOUNT_NUMBER>:root"
      },
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ]
    }
  ]
}

Other notes:

  • The ECR permission GUI also states an asterisk is needed: Statement[0].Principal must match the following: "/\*/" @ Statement[0].Principal
  • I've unblocked myself by using an escape hatch.

Workaround

        const cfnRepository = appEcrRepo.node.defaultChild as ecr.CfnRepository;

        cfnRepository.repositoryPolicyText = {
            "Version": "2008-10-17",
            "Statement": [
              {
                "Effect": "Allow",
                "Principal": {
                  "AWS": "arn:aws:iam::<ACCOUNT_NUMBER>:root"
                },
                "Action": [
                  "ecr:BatchCheckLayerAvailability",
                  "ecr:BatchGetImage",
                  "ecr:GetDownloadUrlForLayer"
                ]
              }
            ]
          }

If you need this in a new issue I'm happy to spin one up.

skinny85

skinny85 commented on Jun 11, 2021

@skinny85
Contributor

Hmm, but the error you get and the resolution don't match each other...?

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "new statement",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ACCOUNT_NUMBER>:root"
      },
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ]
    }
  ]
}

This does not contain a * in the Principal of the Statement...?

danwiltshire

danwiltshire commented on Jun 11, 2021

@danwiltshire
ContributorAuthor

Correct, that seems to be the second available solution.

If you were to take a role ARN and put an asterisk in, that works to.

skinny85

skinny85 commented on Jun 11, 2021

@skinny85
Contributor

But an asterisk where? 🤔 Just tack it on randomly at the end of the Role ARN?

danwiltshire

danwiltshire commented on Jun 14, 2021

@danwiltshire
ContributorAuthor

Yeah pretty much. I wonder if ECR just doesn't allow granting access to roles? Looking at the AWS docs granting a role isn't listed: https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html

23 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @skinny85@danwiltshire

      Issue actions

        (aws-codepipeline-actions): TagParameterContainerImage unusable cross-account · Issue #15070 · aws/aws-cdk