Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(event-targets): ecsTask uses invalid task definition arn in policy #31615

Merged
merged 10 commits into from
Oct 7, 2024

Conversation

samson-keung
Copy link
Contributor

Issue # (if applicable)

Closes #30390 .

Reason for this change

This is extending a closed PR #30484 by @jwoehrle . I couldn't update that PR so I am creating this new one.

Reason for this change is due to a AWS ECS campaign where they are asking customers to add task definition revision number (or wildcard as the revision number) to IAM policies.

Description of changes

When adding permission to the Events Role to allow it to use the task definition, check if the task definition arn has a revision number, if yes, do nothing, if not, add the wildcard *. This is only done when the task definition arn is not using any token.

Description of how you validated changes

Unit tests and Integ tests are added.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added bug This issue is a bug. effort/small Small work item – less than a day of effort labels Oct 1, 2024
@aws-cdk-automation aws-cdk-automation requested a review from a team October 1, 2024 22:28
@github-actions github-actions bot added the p1 label Oct 1, 2024
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Oct 1, 2024
@msambol
Copy link
Contributor

msambol commented Oct 2, 2024

Per #30751, without the * isn't valid. I believe you can copy this PR and simplify the code here.

@samson-keung samson-keung marked this pull request as ready for review October 2, 2024 19:58
const revisionAtEndPattern = /:[0-9]+$/;
const hasRevision = revisionAtEndPattern.test(this.taskDefinition.taskDefinitionArn);
needsRevisionWildcard = !hasRevision;
}
Copy link
Contributor

@msambol msambol Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code isn't needed. As mentioned in #30751, the task definition without the trailing :* isn't a valid ARN.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @msambol , thanks for taking time to review. It is possible for taskDefinitionArn to have a revision number that isn't *, hence, this if block. When there is already a revision number, we shouldn't append :*. I left a comment in the PR you linked about this case.

Copy link
Contributor

@msambol msambol Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The * means it will match all revision numbers (it's a wildcard).

Copy link
Contributor Author

@samson-keung samson-keung Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That is correct. It is also possible that customer may want to restrict the IAM policy resource to specific revision number.

Sample code of such case where customer is specifying the revision number MyTask:19:

import { Duration, Stack, type StackProps } from 'aws-cdk-lib';
import { Cluster, FargateTaskDefinition, NetworkMode } from 'aws-cdk-lib/aws-ecs';
import { Rule, Schedule } from 'aws-cdk-lib/aws-events';
import { EcsTask } from 'aws-cdk-lib/aws-events-targets';
import { Role } from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class TestCdkStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const cluster = new Cluster(this, 'Cluster');
    const taskDefinition = FargateTaskDefinition.fromFargateTaskDefinitionAttributes(this, "TaskDefImport", {
      taskDefinitionArn: "arn:aws:ecs:us-west-2:123456789101:task-definition/MyTask:19",
      taskRole: Role.fromRoleArn(this, "RoleImport", "arn:aws:iam::123456789101:role/MyTaskRole"),
      networkMode: NetworkMode.AWS_VPC,
    });
    new Rule(this, "Rule", {
      targets: [new EcsTask({
        cluster,
        taskDefinition
      })],
      schedule: Schedule.rate(Duration.days(1)),
    });
  }
}

Copy link
Contributor

@msambol msambol Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. Appreciate the time for checking. I will open an issue about the StepFunction ECS task.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, could you move this code to a function and write unit tests for it? I think it'd be easier to follow. Similar to https://github.com/msambol/aws-cdk/blob/main/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/ecs/run-task.ts#L379-L396.

    let needsRevisionWildcard = false;
    if (!cdk.Token.isUnresolved(this.taskDefinition.taskDefinitionArn)) {
      const revisionAtEndPattern = /:[0-9]+$/;
      const hasRevision = revisionAtEndPattern.test(this.taskDefinition.taskDefinitionArn);
      needsRevisionWildcard = !hasRevision;
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously different purpose of the function but similar pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving it out to a public method to allow unit testing means exposing it for potential public use, which will become a API contract that cannot have any breaking change. I would prefer keeping it private and local in this method for now. The unit tests added in this PR are primarily focusing on this block of code.

Copy link
Contributor

@msambol msambol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comments.

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Oct 4, 2024
Co-authored-by: Michael Sambol <sambol.michael@gmail.com>
Match.objectLike({
Action: 'ecs:RunTask',
Resource: {
Ref: 'TaskDef54694570',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this policy have the trailing :* ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses a CloudFormation (CFN for short) Ref token to reference the TaskDefinition resource. According to the CFN doc, the token will resolve to the TaskDefinition ARN >with< the revision number (but not *).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼 – I wanted to make sure there was either a revision number or a * at the end.

Co-authored-by: Michael Sambol <sambol.michael@gmail.com>

new IntegTest(app, 'IntegTest-EcsImportedTaskDefinition', {
testCases: [stack],
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samson-keung I think this integration test should in aws-event-targets , no ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! Let me move it.

}
},
"Effect": "Allow",
"Resource": "arn:aws:ecs:test-region:12345678:task-definition/TaskDef:*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I wanted to see 👍🏼

@@ -1095,3 +1096,100 @@ test.each([
],
});
});

test('Non-imported TaskDefinition role is targeting by Ref', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could you change the verbiage here? Based on the name, I'm not certain what it's testing.

const revisionAtEndPattern = /:[0-9]+$/;
const hasRevision = revisionAtEndPattern.test(this.taskDefinition.taskDefinitionArn);
needsRevisionWildcard = !hasRevision;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving it out to a public method to allow unit testing means exposing it for potential public use, which will become a API contract that cannot have any breaking change. I would prefer keeping it private and local in this method for now. The unit tests added in this PR are primarily focusing on this block of code.

Copy link
Contributor

@msambol msambol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Sorry for the back and forth!

Copy link
Contributor

@GavinZZ GavinZZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

mergify bot commented Oct 7, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Oct 7, 2024
Copy link
Contributor

mergify bot commented Oct 7, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 2d8333d
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Copy link
Contributor

mergify bot commented Oct 7, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 4ada3ea into aws:main Oct 7, 2024
12 checks passed
Copy link

github-actions bot commented Oct 7, 2024

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug. contribution/core This is a PR that came from AWS. effort/small Small work item – less than a day of effort p1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(event-targets): EcsTask uses invalid task definition arn in policy
4 participants