2
votes

Hi I am working on AWS CDK in python. I am creating policy document. Previously I writtten cloud formation template for the same policy and it was working fine. Below is cloud formation policy.

MWSECSServiceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: [ecs.amazonaws.com]
            Action: ['sts:AssumeRole']
      Path: /
      Policies:
        - PolicyName: "ecs-service-role"
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - elasticloadbalancing:DeregisterInstancesFromLoadBalancer
                  - elasticloadbalancing:DeregisterTargets
                  - elasticloadbalancing:RegisterInstancesWithLoadBalancer
                  - elasticloadbalancing:RegisterTargets
                # yamllint disable-line rule:line-length
                Resource:
                  # yamllint disable-line rule:line-length
                  - !Sub 'arn:aws:elasticloadbalancing:*:${AWS::AccountId}:loadbalancer/app/mws-*'
                  # yamllint disable-line rule:line-length
                  - !Sub 'arn:aws:elasticloadbalancing:*:${AWS::AccountId}:listener-rule/app/mws-*'
                  # yamllint disable-line rule:line-length
                  - !Sub 'arn:aws:elasticloadbalancing:*:${AWS::AccountId}:listener/app/mws-*'
                  # yamllint disable-line rule:line-length
                  - !Sub 'arn:aws:elasticloadbalancing:*:${AWS::AccountId}:targetgroup/mws-*'

              - Effect: Allow
                Action:
                  - ec2:Describe*
                  - ec2:AuthorizeSecurityGroupIngress
                  - elasticloadbalancing:Describe*
                Resource: '*'

Now I am writing AWS CDK as below.

 MWSECSServiceRole = iam.Role(self, 'MWSECSServiceRole',
          assumed_by=new ServicePrincipal('ecs.amazonaws.com'))

        MWSECSServiceRole.add_to_policy(iam.PolicyStatement(
        effect=iam.Effect.ALLOW,
        resources=["arn:aws:elasticloadbalancing:*:${AWS::AccountId}:loadbalancer/app/mws-*","arn:aws:elasticloadbalancing:*:${AWS::AccountId}:listener-rule/app/mws-*","arn:aws:elasticloadbalancing:*:${AWS::AccountId}:listener/app/mws-*","arn:aws:elasticloadbalancing:*:${AWS::AccountId}:targetgroup/mws-*"],
        actions=["elasticloadbalancing:DeregisterInstancesFromLoadBalancer","elasticloadbalancing:DeregisterTargets","elasticloadbalancing:RegisterInstancesWithLoadBalancer","elasticloadbalancing:RegisterTargets"]
        ))

        MWSECSServiceRole.add_to_policy(iam.PolicyStatement(
        effect=iam.Effect.ALLOW,
        resources=["*"],
        actions=["ec2:AuthorizeSecurityGroupIngress","ec2:Describe*","elasticloadbalancing:Describe*"]
        ))

This will generate resources for example arn:aws:elasticloadbalancing:*:${AWS::AccountId}:loadbalancer/app/mws-* but what I need is - !Sub 'arn:aws:elasticloadbalancing:*:${AWS::AccountId}:loadbalancer/app/mws-*'. So how to use !Sub in AWS CDK? Can someone help me in this?

1
Unfamiliar with CDK, but found this in the docs. Does it help? docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core/Aws.html Looks like you can pull the account id from there. You would then substitute it in the string with standard python string interpolation - adamkgray

1 Answers

0
votes

So I've only recently started using AWS CDK with Python. Thought I'd answer it the event it helps someone else

We're migrating existing cfn templates with CDK and we want to leverage code abstraction and feed-in parameters to generate cfn templates.

I came across the same issue and did the following:

import core:

from aws_cdk import (
    core
)

outside of your CDK class declare the CDK Function object:

Fn = core.Fn

Inside your CDK class create a function similar to:

def checkFnSubRequired(self, content):
    if re.search(r'\${.*}', content):
        return Fn.sub(content)
    else:
        return content

The function lets you take any string that might require a substitute and return the substituted object, for example:

resources=["arn:aws:elasticloadbalancing:*:${AWS::AccountId}"]

changes to the following:

resources=[self.checkFnSubRequired("arn:aws:elasticloadbalancing:*:${AWS::AccountId}")]