Deploy EC2 instance using the AWS CDK for Python
Setup for macOS
Make sure you do this setup first:
Create the CDK Project
Open a Terminal and type this to the create project directory:
Create the project:
nvm use 20.16.0
# init project and create Python virtual environment
cdk init app --language python --generate-only
# activate virtual environment
source .venv/bin/activate
# install Python packages
pip install -r requirements.txt
pip install -r requirements-dev.txt
The result should be this file tree:
tree -L 3
.
├── README.md
├── app
│ ├── __init__.py
│ └── app_stack.py
├── app.py
├── cdk.json
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_app_stack.py
Define a single instance stack that runs Nginx
Update stack code
Paste this code in app/app_stack.py
:
from aws_cdk import (
Stack,
aws_ec2 as ec2,
aws_iam as iam,
)
from constructs import Construct
class AppStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# Use the default VPC
vpc = ec2.Vpc.from_lookup(self, "VPC", is_default=True)
# Create a security group
security_group = ec2.SecurityGroup(
self, "NginxSecurityGroup",
vpc=vpc,
description="Allow HTTP traffic",
allow_all_outbound=True
)
security_group.add_ingress_rule(
ec2.Peer.any_ipv4(),
ec2.Port.tcp(80),
"Allow HTTP traffic from anywhere"
)
# Create a role for the EC2 instance
role = iam.Role(
self, "NginxInstanceRole",
assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")
)
# Create the EC2 instance
instance = ec2.Instance(
self, "NginxInstance",
instance_type=ec2.InstanceType("t2.micro"),
machine_image=ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2),
vpc=vpc,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
role=role,
security_group=security_group,
)
# Add user data to install and start nginx
instance.add_user_data(
"yum update -y",
"amazon-linux-extras install nginx1 -y",
"systemctl start nginx",
"systemctl enable nginx"
)
# Output the public IP of the instance
self.output_props = {
'instance_public_ip': instance.instance_public_ip
}
Update app code
Paste this code into app.py
:
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from app.app_stack import AppStack
app = cdk.App()
AppStack(
app,
construct_id="NginxEc2Stack",
env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),
)
app.synth()
Deploy
Print the CloudFormation template for the stack. You should see the CloudFormation template without any errors:
Bootstrap the CDK environment. This should be done only once per account. Skip this step if you have done it already. See Bootstrapping for details: Deploy the stack:Test Deployment
Check that you can browse the nginx
default site:
key="aws-ec2-key"
instance="NginxEc2Stack/NginxInstance"
instance_public_ip=$(aws ec2 describe-instances \
--filters \
Name=tag:Name,Values=$instance \
Name=instance-state-name,Values=running \
| jq -r '.Reservations[0].Instances[0].PublicIpAddress')
open http://$instance_public_ip
Cleanup
Delete the stack:
Opptional: To delete the CDKToolkit
CloudFormation template which is created by the AWS CDK during bootstrap:
cdk-<hash>-assets-<account_id>-<region>
. This bucket will not be deleted automatically and will remain in your account if not deleted manually.
GitHub Repository
The code for this project is available in the aws-ec2-cdk-python repository.