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

(module name): (short issue description) #22773

Closed
JoshMcCullough opened this issue Nov 4, 2022 · 5 comments
Closed

(module name): (short issue description) #22773

JoshMcCullough opened this issue Nov 4, 2022 · 5 comments
Assignees
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management

Comments

@JoshMcCullough
Copy link

JoshMcCullough commented Nov 4, 2022

Describe the bug

Additional RoleDefaultPolicy5FFB7DAB added to template during synth.

Expected Behavior

Existing role already includes the policy described in RoleDefaultPolicy5FFB7DAB, so it shouldn't be included in the template.

Current Behavior

No errors, stack deploys okay but template contains extraneous data, maybe?

Reproduction Steps

Stack:

export class MyStack extends Stack {
  private params: Params;

  buildStack() {
    const deadLetterQueue = this.buildDeadLetterQueue();
    const role = this.buildRole(deadLetterQueue, startTimeParam);
    const fn = this.buildFunction(deadLetterQueue, role);

    this.buildEventRule(deadLetterQueue, fn);
  }

  buildDeadLetterQueue() {
    const { stackName } = this.params;

    return new SQS.Queue(this, RESOURCE_IDS.DeadLetterQueue, {
      queueName: `${stackName}_dl`,
    });
  }

  buildRole(deadLetterQueue: SQS.Queue) {
    const { stackName } = this.params;

    return new IAM.Role(this, RESOURCE_IDS.Role, {
      roleName: stackName,
      assumedBy: new IAM.ServicePrincipal('lambda.amazonaws.com'),
      managedPolicies: [
        IAM.ManagedPolicy.fromManagedPolicyArn(this, 'AWSLambdaBasicExecutionRole', 'arn:region:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'),
      ],
      inlinePolicies: {
        'dead-letter-queue_send-message': new IAM.PolicyDocument({
          statements: [new IAM.PolicyStatement({
            effect: IAM.Effect.ALLOW,
            actions: [IAMActions.SQS.SEND_MESSAGE],
            resources: [deadLetterQueue.queueArn],
          })],
        }),
      }
    });
  }

  buildFunction(encryptionKey: KMS.IKey, deadLetterQueue: SQS.Queue, bucket: S3.Bucket, startTimeParam: SSM.StringParameter, role: IAM.Role) {
    const { stackName } = this.params;

    return new NodeLambda.NodejsFunction(this, RESOURCE_IDS.Function, {
      functionName: stackName,
      runtime: Lambda.Runtime.NODEJS_16_X,
      entry: path.join(__dirname, '/../src/handler.ts'),
      handler: 'handleEvent',
      role,
      architecture: Lambda.Architecture.X86_64,
      memorySize: 256,
      deadLetterQueue,
      timeout: Duration.minutes(15),
    });
  }

  buildEventRule(deadLetterQueue: SQS.Queue, fn: Lambda.Function) {
    return new Events.Rule(this, RESOURCE_IDS.FunctionSchedule, {
      description: `Runs the ${fn.functionName} lambda every 5 minutes.`,
      schedule: Events.Schedule.rate(Duration.minutes(5)),
      targets: [new EventTargets.LambdaFunction(fn, {
        deadLetterQueue,
        retryAttempts: 3,
      })]
    });
  }
}

Generated Template:

Resources:
  DeadLetterQueue9F481546:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: my-stack_dl
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: my-stack/DeadLetterQueue/Resource
  Role1ABCC5F0:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - arn:region:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action: sqs:SendMessage
                Effect: Allow
                Resource:
                  Fn::GetAtt:
                    - DeadLetterQueue9F481546
                    - Arn
            Version: "2012-10-17"
          PolicyName: queue_send-message
      RoleName: my-stack
    Metadata:
      aws:cdk:path: my-stack/Role/Resource
  RoleDefaultPolicy5FFB7DAB:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: sqs:SendMessage
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - DeadLetterQueue9F481546
                - Arn
        Version: "2012-10-17"
      PolicyName: RoleDefaultPolicy5FFB7DAB
      Roles:
        - Ref: Role1ABCC5F0
    Metadata:
      aws:cdk:path: my-stack/Role/DefaultPolicy/Resource
  Function76856677:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: ...
        S3Key: fae71eee636f198d6c41252ecf68776815625622f8346272b5920b612a6273b6.zip
      Role:
        Fn::GetAtt:
          - Role1ABCC5F0
          - Arn
      Architectures:
        - x86_64
      DeadLetterConfig:
        TargetArn:
          Fn::GetAtt:
            - DeadLetterQueue9F481546
            - Arn
      FunctionName: my-stack
      Handler: index.handleEvent
      MemorySize: 256
      Runtime: nodejs16.x
      Timeout: 900
    DependsOn:
      - RoleDefaultPolicy5FFB7DAB
      - Role1ABCC5F0
    Metadata:
      aws:cdk:path: my-stack/Function/Resource
      aws:asset:path: asset.fae71eee636f198d6c41252ecf68776815625622f8346272b5920b612a6273b6
      aws:asset:is-bundled: true
      aws:asset:property: Code
  FunctionSchedule755EA547:
    Type: AWS::Events::Rule
    Properties:
      Description:
        Fn::Join:
          - ""
          - - "Runs the "
            - Ref: Function76856677
            - " lambda every 5 minutes."
      ScheduleExpression: rate(5 minutes)
      State: ENABLED
      Targets:
        - Arn:
            Fn::GetAtt:
              - Function76856677
              - Arn
          Id: Target0
    Metadata:
      aws:cdk:path: my-stack/FunctionSchedule/Resource
  FunctionScheduleAllowEventRulemystackFunction0694A6EAAAB4168E:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Fn::GetAtt:
          - Function76856677
          - Arn
      Principal: events.amazonaws.com
      SourceArn:
        Fn::GetAtt:
          - FunctionSchedule755EA547
          - Arn
    Metadata:
      aws:cdk:path: my-stack/FunctionSchedule/AllowEventRulemystackFunction0694A6EA
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.50.0

Framework Version

No response

Node.js Version

18.4.0

OS

Manjaro Linux 22

Language

Typescript

Language Version

4.8.4

Other information

Possibly related to:

@JoshMcCullough JoshMcCullough added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Nov 4, 2022
@github-actions github-actions bot added the @aws-cdk/aws-iam Related to AWS Identity and Access Management label Nov 4, 2022
@peterwoodworth
Copy link
Contributor

Role.withoutPolicyUpdates() will return a role which cannot have policies added to it. Refer to the role like this if you don't want additional policies to be added

@peterwoodworth peterwoodworth removed bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Nov 4, 2022
@github-actions
Copy link

github-actions bot commented Nov 4, 2022

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@JoshMcCullough
Copy link
Author

@peterwoodworth thanks, I'll do that -- question is, why was the duplicate policy added, though?

@peterwoodworth
Copy link
Contributor

@JoshMcCullough When passing in a queue to a Lambda Function, the Function will grant permissions to its role send a message to its queue. That's done in our code here:

this.addToRolePolicy(new iam.PolicyStatement({
actions: ['sqs:SendMessage'],
resources: [deadLetterQueue.queueArn],
}));

The role of the function is the role you passed in to the function, so that role is having this policy added to it because that's what this construct does to ensure the role has correct permissions.

For people who don't want our constructs to add policies automatically like this, we support the option to pass in a role which cannot have policies added to it.

@JoshMcCullough
Copy link
Author

Understood. I was suggesting that before adding a role, it would be cleaner and more clear (but perhaps have no functional affect) to first check if a policy with the same (or more) actions already exists for the resource. That'd me we don't have to worry about immutability because if we set up our role correctly beforehand, then we're good, or if we'd rather let CDK manage it, then we'd also be good -- win win, IMO. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management
Projects
None yet
Development

No branches or pull requests

3 participants