AWS CDK

Useful Codes

Printing variable to Terminal

cdk.CfnOutput(self,
    'API Endpoint',
    description='API Endpoint',
    value=http_api.api_endpoint
)

Example output

# Outputs:
AWSStack.APIEndpoint = https://01ffv5caw3.execute-api.us-east-1.amazonaws.com

Using Lambda function

lambda_func = cdk.aws_lambda.Function(
  self, 'TextClassificationFunc',
  runtime=cdk.aws_lambda.Runtime.PYTHON_3_9,
  handler="sample.handler",
  code=cdk.aws_lambda.Code.from_asset(os.path.join(DIRNAME, "app/others/inference/src")),
  vpc=vpc,
  initial_policy=[policy],
  environment={
    "env_var1": "value 1",
    "env_var2": "value 2",
  }
)

Deploying initial code

cdk bootstrap
cdk synth
cdk deploy

cdk bootstrap: used to create CDKToolkit CloudFormation

cdk deploy: push updated packages to prod

Example AWS stacks

Route53 - API Gateway <-> Lambda (in VPC) <-> EFS
                / \
                 |
VS Code   ->    ECR

This is infrastructure as a code , defined by .cdk file. By default, it will deploy 2 CloudFormation stacks: CDKToolkit (auto generated by AWS to deploy AWS CDK apps to this environment) and the prod server.

Route53: Used for client side to enable api.example.com that will call invoke url in API Gateway

API Gateway: Pass invoke url to Lambda with predefined parameter

EFS: Host the tokenizer and finetuned NLP model and make it persists in /mnt/ folder. To access this manually, spin up a temporary EC2 (click mount EFS from console)

ECR: Host Docker, defined by Dockerfile. It contains:

  • pip packages (python version, transformers from hugging face, pandas, etc)

  • Lambda codes (handler, utilities/helper for preprocess text)

Note:

  • This will create a CloudFormation stacks

  • Everytime you make changes, use cdk synth; cdk deploy to update the code.

  • If you change some components (EC2, EFS, etc) manually, there is a chance the CloudFormation does not know about this. This will cause error when you try to delete CloudFormation Stack. To fix this, delete the component manually until CloudFormation stack can be deleted. To avoid this in the future, try to always create component from AWS CDK via cdk deploy . If you always use cdk deploy to update component, then when you are doing cdk deploy , it will always succeed.

Destroying code in AWS prod

cdk destroy

Creating VPC

  • To fix NAT Gateway requirement, it’s cheaper to spin up NAT instance using AWS EC2. The price for 2 instances (2 * $15/mo) = $30/mo, which is currently cheaper than managed NAT ($100/mo).

  • NAT Gateway is required by default in order for AWS Lambda to send back the data (outbound). If you set NAT Gateway to 0, AWS Lambda will not be able to return response.

# Example code
# Note: If you use, your AWS Lambda will lose access to internet for outbound

subnet_configurations = [aws_ec2.SubnetConfiguration(
                    name='public',
                    subnet_type=aws_ec2.SubnetType.PUBLIC,
                    map_public_ip_on_launch=True,
                    cidr_mask=24
                ),
                aws_ec2.SubnetConfiguration(
                    name='isolated',
                    subnet_type=aws_ec2.SubnetType.PRIVATE_ISOLATED
                )
            ]
vpc = aws_ec2.Vpc(self, 'Vpc',
            nat_gateways=0,
            subnet_configuration=subnet_configurations
        )

Troubleshooting

AWS Lambda throws some random errors

Perform cdk destroy , then delete CDKToolkit stack in CloudFormation

Error when performing cdk destroy, multiple DELETE_FAILED

  • Delete CloudFormation stack using console. If there is an error, take a look at what’s failing, and delete manually one by one. For example, if there is an error deleting s3 bucket, then go to s3, empty bucket, and delete bucket manually.

  • If this keeps happening, check the IAM permission in CDK. Adding extra permissions might help. For example:

policy = cdk.aws_iam.PolicyStatement(
    actions=['s3:*Object', 's3:ListBucket', 'ec2:DeleteInternetGateway',
        'ec2:*VpcEndpoint*'],
    resources=['*'])

Last updated