To put it briefly, the AWS Cloud Development Kit (AWS CDK) is an open-source software development framework for defining cloud infrastructure in code (IaaC) and provisioning it through AWS CloudFormation.
The key difference is that you can write Infrastructure as code in your preferred language, such as TypeScript, Python, JavaScript, Java, or any supported language, rather than scripting CloudFormation in JSON or YAML.
Other, JVM and .NET CLR languages may also be used in theory, but we do not offer official support at this time.
Select your preferred language and use programming elements like parameters, conditionals, loops, composition, and inheritance to define the desired outcome of your infrastructure.
Use the same programming language to define your infrastructure and your application logic. Receive the benefits of developing infrastructure in your preferred IDE (Integrated Development Environment), such as syntax highlighting and intelligent code completion.
AWS CDK integrates with AWS CloudFormation to deploy and provision your infrastructure on AWS. AWS CloudFormation is a managed AWS service that offers extensive support of resource and property configurations for provisioning services on AWS. With AWS CloudFormation, you can perform infrastructure deployments predictably and repeatedly, with rollback on error. If you are already familiar with AWS CloudFormation, you don’t have to learn a new IaC management service when getting started with the AWS CDK.
Develop faster by using and sharing reusable components called constructs. Use low-level constructs to define individual AWS CloudFormation resources and their properties. Use high-level constructs to quickly define larger components of your application, with sensible, secure defaults for your AWS resources, defining more infrastructure with less code. Create your own constructs that are customized for your unique use cases and share them across your organization or even with the public.
In this project, we’ll build a secure cloud architecture using AWS CDK and TypeScript. The architecture includes:
In this step, you create a new CDK project. A CDK project should be in it’s own directory, with it’s own local module dependencies.
1. From a starting directory of your choice, create and navigate to a directory named my-cdk-project:
$ mkdir my-cdk-project && cd my-cdk-project
Ensure the name of your project directory is my-cdk-project, exactly as shown here. The CDK CLI uses this directory name to name resources within your CDK code. If the different directory name is used, you may face an issues while following the instructions.
2. From the my-cdk-project directory, initialize a new CDK project using the AWS CDK CLI “cdk init” command. Specify the app template and your preferred programming language with the “–language” option: TypeScript.
$ cdk init app --language typescript
The cdk init command creates a structure of files and folders within the my-cdk-project directory to help organize the source code for your CDK app. Take a moment to explore the CDK project.
In most programming environments, you build or compile code after making changes. This isn’t necessary with the AWS CDK since the CDK CLI will automatically perform this step. However, you can still build manually when you want to catch syntax and type errors. The following is an example:
$ npm run build
For this tutorial, the app will be deployed into your default AWS environment. Assuming the current environment is configured and bootstrapped during the getting started process. If not and need to deploy this application into another environment, user must specify the environment in CDK code and bootstrap the environment. For instructions, view the following:
$ cdk bootstrap
At this point, now you should have a CDK app containing a single CDK stack. To verify, use the CDK CLI list command to display all the stacks. The output should display a stack named HelloCdkProjectStack.
$ cdk list
If you don’t see this output, verify that you are in the correct working directory of your project and try again. If the stack still doesn’t appear on screen, repeat the Step 1 and try again.
Edit the files in the lib
directory to define your AWS resources. By default, “lib/my-cdk-project-stack.ts"
is created for you. Add resources to this file using CDK constructs.
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Vpc, SubnetType, Instance, InstanceType, InstanceClass, InstanceSize, AmazonLinuxImage, SecurityGroup, Peer, Port}
from 'aws-cdk-lib/aws-ec2';
export class MyCdkProjectStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// VPC with 3 public and 3 private subnets
const vpc = new Vpc(this, 'MyVpc', {
natGateways: 1,
availabilityZones: [ 'us-east-1a','us-east-1b', 'us-east-1c'],
subnetConfiguration: [
{
cidrMask: 24,
name: 'PublicSubnet',
subnetType: SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: 'PrivateSubnet',
subnetType: SubnetType.PRIVATE_WITH_EGRESS,
},
],
});
// Security Group for Public Instance
const publicSecurityGroup = new SecurityGroup(this, 'PublicSG', {
vpc,
allowAllOutbound: true,
});
publicSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(22), 'Allow SSH access');
// Security Group for Private Instance
const privateSecurityGroup = new SecurityGroup(this, 'PrivateSG', {
vpc,
allowAllOutbound: true,
});
privateSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(22), 'Allow SSH access');
privateSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(80), 'Allow HTTP traffic');
privateSecurityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(443), 'Allow HTTP traffic');
// Public Instance
new Instance(this, 'PublicInstance', {
vpc,
instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
machineImage: new AmazonLinuxImage(),
securityGroup: publicSecurityGroup,
vpcSubnets: { subnetType: SubnetType.PUBLIC },
});
// Private Instance
new Instance(this, 'PrivateInstance', {
vpc,
instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
machineImage: new AmazonLinuxImage(),
securityGroup: privateSecurityGroup,
vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },
});
}
}
const app = new cdk.App();
new MyCdkProjectStack(app, 'MyCdkProjectStack');
app.synth();
In this step, we’ll use the command to deploy the CDK stack. This command retrieves the generated CloudFormation template and deploys it through AWS CloudFormation service, which provisions your resources as part of a CloudFormation stack.
From the root of your project, run the following. Confirm changes if prompted:
$ cdk deploy
In this step, prepare for deployment by synthesizing a CloudFormation template with the CDK command. The command will performs basic validation of your CDK code, runs CDK app, and generates a CloudFormation template from CDK stack.
If your app contains more than one stack, you must specify which stacks to synthesize. Since the app contains a single stack, the CDK CLI will automatically detects the stack to synthesize.
If you don’t synthesize a template, the CDK CLI will automatically perform this step when you deploy. However, it’s recommend that you perform step before each deployment to check for synthesis errors.
Before synthesizing a template, user can optionally build your application to catch syntax and type errors. For instructions, see Step 2: Build your CDK app.
To synthesize a CloudFormation template, run the following from the root of the project:
$ cdk synth
If successful, the CDK CLI will output a YAML–formatted CloudFormation template to stdout and save a JSON–formatted template in the cdk.out directory of your project.
By defining a single L2 construct, the AWS CDK creates an extensive CloudFormation template containing your Lambda resources, along with the permissions and glue logic required for your resources to interact within your application.
In this process, destroy command is used to delete the application deployed on cloud. This command removes the CloudFormation stack associated with your CDK stack, which includes the resources created by CDK.
To delete the application, run the cdk destroy command and confirm your request to delete the application. The following is an example:
$ cdk destroy
Additionally, you may create more extensive cloud resources, autoscaling groups, Dynamo DB, RDS, Serverless Lambda Functions, SQS, SNS and more with the help of CDK. Here, we'll learn more about autoscaling groups and how to use CDK to make them happen.
Auto-scaling group is a powerful feature in AWS that allows your applications to handle varying loads by dynamically adjusting the number of instances running. In this article, we will walk through setting up an Auto-Scaling Group (ASG) with scaling policies using the AWS CDK and TypeScript. This setup will monitor the CPU utilization of ec2 and scale in or out based on the defined thresholds.
This type of scaling scales in and out in deterministic steps that you configure, in response to metric values.
After deployment, your Auto Scaling Group will automatically adjust the number of instances based on the CPU utilization. You can monitor the scaling activities in the AWS Management Console under the EC2 Auto Scaling section.
Edit the “lib/my-cdk-project-stack.ts"
file to define the VPC, Auto Scaling Group, and scaling policies.
Do perform all the above steps. (Step 1 to Step 4)
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { AutoScalingGroup, CfnLaunchConfiguration } from 'aws-cdk-lib/aws-autoscaling';
import { Metric } from 'aws-cdk-lib/aws-cloudwatch';
import { Role, ServicePrincipal, ManagedPolicy } from 'aws-cdk-lib/aws-iam';
export class MyCdkProjectStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Auto Scaling Group IAM Police
const asgRole = new Role(this, 'AsgRole', {
assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ReadOnlyAccess')],
});
// Create a VPC
const vpc = new Vpc(this, 'MyVpc', {
maxAzs: 3
});
// Auto Scaling Group
const asg = new AutoScalingGroup(this, 'MyAutoScalingGroup', {
vpc,
instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
machineImage: new AmazonLinuxImage(),
minCapacity: 1,
maxCapacity: 5,
desiredCapacity: 2,
role: asgRole,
vpcSubnets: { subnetType: SubnetType.PUBLIC },
});
// Scaling Policy Based on CPU Utilization
asg.scaleOnMetric('ScaleOnCPU', {
metric: new Metric({
namespace: 'AWS/EC2',
metricName: 'CPUUtilization', //metric which is used for scaling
}),
scalingSteps: [
{ upper: 20, change: -1 },
{ lower: 60, change: +1 },
{ lower: 80, change: +2 },
],
adjustmentType: cdk.aws_autoscaling.AdjustmentType.CHANGE_IN_CAPACITY,
});
}
}
const app = new cdk.App();
new MyCdkProjectStack(app, 'MyCdkProjectStack');
app.synth();
This instructions shows how to build a secure cloud architecture using AWS CDK and TypeScript. The setup provides resource isolation, secure access, and scalability based on demand. We also explored how to configure an Auto-Scaling Group with scaling policies using AWS CDK and TypeScript. By monitoring CPU utilization, your application can handle varying loads efficiently, ensuring optimal performance and cost management while following best practices for AWS infrastructure design.