forked from aws-samples/aws-cdk-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add VPC, EC2 Python Example (aws-samples#204)
This pull request is aimed at creating the following Python Examples: - Import VPC - Create new VPC with 2 AZs and 6 Subnets, Public, Private and DataBase. - Sharing VPC between two stacks - Create ALB/EC2/AutoscalingGroup in the VPC - How to define EC2 to specify AMI or auto-selection - Define property override for EC2 Instance with BlockStorageMapping - Define userdata for EC2 to setup httpd - Create NAT GW and Bastion - Chain the Security Groups
- Loading branch information
1 parent
9ba1cf1
commit a88f312
Showing
18 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Create EC2 in an existing VPC with AWS CDK Python | ||
|
||
This is a project to create a new EC2 in an existing VPC on AWS with the AWS Cloud Development Kit. | ||
|
||
This project also demonstrates: | ||
* Using customized user data of EC2 | ||
* Customize multiple EBS volume | ||
* Specify AMI id | ||
* Security groups allow SSH access from internet | ||
|
||
## Useful commands | ||
|
||
* `cdk ls` list all stacks in the app | ||
* `cdk synth` emits the synthesized CloudFormation template | ||
* `cdk deploy` deploy this stack to your default AWS account/region | ||
* `cdk diff` compare deployed stack with current state | ||
* `cdk docs` open CDK documentation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from aws_cdk import core | ||
|
||
from cdk_vpc_ec2.cdk_vpc_ec2_stack import CdkVpcEc2Stack | ||
|
||
# Define your account id to make import vpc work | ||
env_cn = core.Environment(account="YOUR_ACCOUNT_ID_WITHOUT_HYPHEN", region="cn-northwest-1") | ||
|
||
app = core.App() | ||
CdkVpcEc2Stack(app, "cdk-vpc-ec2", env=env_cn) | ||
|
||
app.synth() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"app": "python3 app.py" | ||
} |
54 changes: 54 additions & 0 deletions
54
python/existing-vpc-new-ec2-ebs-userdata/cdk_vpc_ec2/cdk_vpc_ec2_stack.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from aws_cdk import core | ||
import aws_cdk.aws_ec2 as ec2 | ||
|
||
vpc_id = "MY-VPC-ID" # Import an Exist VPC | ||
ec2_type = "t2.micro" | ||
key_name = "id_rsa" | ||
linux_ami = ec2.GenericLinuxImage({ | ||
"cn-northwest-1": "AMI-ID-IN-cn-northwest-1-REGION", # Refer to an Exist AMI | ||
"eu-west-1": "AMI-ID-IN-eu-west-1-REGION" | ||
}) | ||
with open("./user_data/user_data.sh") as f: | ||
user_data = f.read() | ||
|
||
|
||
class CdkVpcEc2Stack(core.Stack): | ||
|
||
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: | ||
super().__init__(scope, id, **kwargs) | ||
|
||
# The code that defines your stack goes here | ||
vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=vpc_id) | ||
|
||
host = ec2.Instance(self, "myEC2", | ||
instance_type=ec2.InstanceType( | ||
instance_type_identifier=ec2_type), | ||
instance_name="mySingleHost", | ||
machine_image=linux_ami, | ||
vpc=vpc, | ||
key_name=key_name, | ||
vpc_subnets=ec2.SubnetSelection( | ||
subnet_type=ec2.SubnetType.PUBLIC), | ||
user_data=ec2.UserData.custom(user_data) | ||
) | ||
# ec2.Instance has no property of BlockDeviceMappings, add via lower layer cdk api: | ||
host.instance.add_property_override("BlockDeviceMappings", [{ | ||
"DeviceName": "/dev/xvda", | ||
"Ebs": { | ||
"VolumeSize": "10", | ||
"VolumeType": "io1", | ||
"Iops": "150", | ||
"DeleteOnTermination": "true" | ||
} | ||
}, { | ||
"DeviceName": "/dev/sdb", | ||
"Ebs": {"VolumeSize": "30"} | ||
} | ||
]) # by default VolumeType is gp2, VolumeSize 8GB | ||
host.connections.allow_from_any_ipv4( | ||
ec2.Port.tcp(22), "Allow ssh from internet") | ||
host.connections.allow_from_any_ipv4( | ||
ec2.Port.tcp(80), "Allow ssh from internet") | ||
|
||
core.CfnOutput(self, "Output", | ||
value=host.instance_public_ip) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-e . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import setuptools | ||
|
||
|
||
with open("README.md") as fp: | ||
long_description = fp.read() | ||
|
||
|
||
setuptools.setup( | ||
name="Import_VPC_Create_EC2", | ||
version="1.0.0", | ||
|
||
description="Import VPC and Create EC2 on it with two EBS and EC2 UserData", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
|
||
author="Huang, Zhuobin (James)", | ||
|
||
package_dir={"": "cdk_vpc_ec2"}, | ||
packages=setuptools.find_packages(where="cdk_vpc_ec2"), | ||
|
||
install_requires=[ | ||
"aws-cdk.core", | ||
"aws-cdk.aws-ec2" | ||
], | ||
|
||
python_requires=">=3.6", | ||
|
||
classifiers=[ | ||
"Development Status :: 4 - Beta", | ||
|
||
"Intended Audience :: Developers", | ||
|
||
"License :: OSI Approved :: Apache Software License", | ||
|
||
"Programming Language :: JavaScript", | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Programming Language :: Python :: 3.6", | ||
"Programming Language :: Python :: 3.7", | ||
"Programming Language :: Python :: 3.8", | ||
|
||
"Topic :: Software Development :: Code Generators", | ||
"Topic :: Utilities", | ||
|
||
"Typing :: Typed", | ||
], | ||
) |
5 changes: 5 additions & 0 deletions
5
python/existing-vpc-new-ec2-ebs-userdata/user_data/user_data.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
sudo yum update -y | ||
sudo yum -y install httpd php | ||
sudo chkconfig httpd on | ||
sudo service httpd start |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Create VPC, EC2 ASG and RDS with AWS CDK Python | ||
|
||
This is a project to create a new VPC, EC2 autoscaling group and RDS on AWS with the AWS Cloud Development Kit. | ||
|
||
This project also demonstrates: | ||
* Create VPC in 3 tier layers of subnets: PUBLIC, PRIVATE and ISOLATED, you can specify the number of AZ and the CIDR. | ||
* Create Bastion instance, NAT Gateway and S3 endpoint | ||
* Create ALB, EC2 Autoscaling group with scaling policy and customize EBS volume | ||
* Creat RDS MySQL M-AZs Database or Aurora | ||
* Create security group and allow access from the other security group: Internet -> ALB -> EC2ASG -> RDS | ||
* Using customized user data of EC2 and specify generation AMI property and do not need to specify the AMI id in every region | ||
|
||
## Architeture | ||
![Architecture](./img_demo_cdk_vpc.png) | ||
|
||
This project create the new VPC part of the architeture. For the existing VPC part, please refer to the project in aws-cdk-examples/existing-vpc-new-ec2-ebs-userdata | ||
|
||
## Useful commands | ||
|
||
* `cdk ls` list all stacks in the app | ||
* `cdk synth` emits the synthesized CloudFormation template | ||
* `cdk deploy` deploy this stack to your default AWS account/region | ||
* `cdk diff` compare deployed stack with current state | ||
* `cdk docs` open CDK documentation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from aws_cdk import core | ||
|
||
from cdk_vpc_ec2.cdk_vpc_stack import CdkVpcStack | ||
from cdk_vpc_ec2.cdk_ec2_stack import CdkEc2Stack | ||
from cdk_vpc_ec2.cdk_rds_stack import CdkRdsStack | ||
|
||
app = core.App() | ||
|
||
vpc_stack = CdkVpcStack(app, "cdk-vpc") | ||
ec2_stack = CdkEc2Stack(app, "cdk-ec2", | ||
vpc=vpc_stack.vpc) | ||
rds_stack = CdkRdsStack(app, "cdk-rds", | ||
vpc=vpc_stack.vpc, | ||
asg_security_groups=ec2_stack.asg.connections.security_groups) | ||
|
||
app.synth() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"app": "python3 app.py" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
from aws_cdk import core | ||
import aws_cdk.aws_ec2 as ec2 | ||
import aws_cdk.aws_elasticloadbalancingv2 as elb | ||
import aws_cdk.aws_autoscaling as autoscaling | ||
|
||
ec2_type = "t2.micro" | ||
key_name = "id_rsa" # Setup key_name for EC2 instance login | ||
linux_ami = ec2.AmazonLinuxImage(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX, | ||
edition=ec2.AmazonLinuxEdition.STANDARD, | ||
virtualization=ec2.AmazonLinuxVirt.HVM, | ||
storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE | ||
) # Indicate your AMI, no need a specific id in the region | ||
with open("./user_data/user_data.sh") as f: | ||
user_data = f.read() | ||
|
||
|
||
class CdkEc2Stack(core.Stack): | ||
|
||
def __init__(self, scope: core.Construct, id: str, vpc, **kwargs) -> None: | ||
super().__init__(scope, id, **kwargs) | ||
|
||
# Create Bastion | ||
bastion = ec2.BastionHostLinux(self, "myBastion", | ||
vpc=vpc, | ||
subnet_selection=ec2.SubnetSelection( | ||
subnet_type=ec2.SubnetType.PUBLIC), | ||
instance_name="myBastionHostLinux", | ||
instance_type=ec2.InstanceType(instance_type_identifier="t2.micro")) | ||
|
||
# Setup key_name for EC2 instance login if you don't use Session Manager | ||
# bastion.instance.instance.add_property_override("KeyName", key_name) | ||
|
||
bastion.connections.allow_from_any_ipv4( | ||
ec2.Port.tcp(22), "Internet access SSH") | ||
|
||
# Create ALB | ||
alb = elb.ApplicationLoadBalancer(self, "myALB", | ||
vpc=vpc, | ||
internet_facing=True, | ||
load_balancer_name="myALB" | ||
) | ||
alb.connections.allow_from_any_ipv4( | ||
ec2.Port.tcp(80), "Internet access ALB 80") | ||
listener = alb.add_listener("my80", | ||
port=80, | ||
open=True) | ||
|
||
# Create Autoscaling Group with fixed 2*EC2 hosts | ||
self.asg = autoscaling.AutoScalingGroup(self, "myASG", | ||
vpc=vpc, | ||
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE), | ||
instance_type=ec2.InstanceType(instance_type_identifier=ec2_type), | ||
machine_image=linux_ami, | ||
key_name=key_name, | ||
user_data=ec2.UserData.custom(user_data), | ||
desired_capacity=2, | ||
min_capacity=2, | ||
max_capacity=2, | ||
# block_devices=[ | ||
# autoscaling.BlockDevice( | ||
# device_name="/dev/xvda", | ||
# volume=autoscaling.BlockDeviceVolume.ebs( | ||
# volume_type=autoscaling.EbsDeviceVolumeType.GP2, | ||
# volume_size=12, | ||
# delete_on_termination=True | ||
# )), | ||
# autoscaling.BlockDevice( | ||
# device_name="/dev/sdb", | ||
# volume=autoscaling.BlockDeviceVolume.ebs( | ||
# volume_size=20) | ||
# # 20GB, with default volume_type gp2 | ||
# ) | ||
# ] | ||
) | ||
|
||
self.asg.connections.allow_from(alb, ec2.Port.tcp(80), "ALB access 80 port of EC2 in Autoscaling Group") | ||
listener.add_targets("addTargetGroup", | ||
port=80, | ||
targets=[self.asg]) | ||
|
||
core.CfnOutput(self, "Output", | ||
value=alb.load_balancer_dns_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from aws_cdk import core | ||
import aws_cdk.aws_ec2 as ec2 | ||
import aws_cdk.aws_rds as rds | ||
|
||
|
||
class CdkRdsStack(core.Stack): | ||
|
||
def __init__(self, scope: core.Construct, id: str, vpc, asg_security_groups, **kwargs) -> None: | ||
super().__init__(scope, id, **kwargs) | ||
|
||
# Ceate Aurora Cluster with 2 instances with CDK High Level API | ||
# Secrets Manager auto generate and keep the password, don't put password in cdk code directly | ||
# db_Aurora_cluster = rds.DatabaseCluster(self, "MyAurora", | ||
# default_database_name="MyAurora", | ||
# engine=rds.DatabaseClusterEngine.AURORA_MYSQL, | ||
# engine_version="5.7.12", | ||
# master_user=rds.Login(username="admin"), | ||
# instance_props=rds.InstanceProps( | ||
# vpc=vpc, | ||
# vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.ISOLATED), | ||
# instance_type=ec2.InstanceType(instance_type_identifier="t2.small") | ||
# ), | ||
# instances=2, | ||
# parameter_group=rds.ClusterParameterGroup.from_parameter_group_name( | ||
# self, "para-group-aurora", | ||
# parameter_group_name="default.aurora-mysql5.7" | ||
# ), | ||
# ) | ||
# for asg_sg in asg_security_groups: | ||
# db_Aurora_cluster.connections.allow_default_port_from(asg_sg, "EC2 Autoscaling Group access Aurora") | ||
|
||
# Alternatively, create MySQL RDS with CDK High Level API | ||
db_mysql_easy = rds.DatabaseInstance(self, "MySQL_DB_easy", | ||
engine=rds.DatabaseInstanceEngine.MYSQL, | ||
engine_version="5.7.22", | ||
instance_class=ec2.InstanceType.of( | ||
ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), | ||
master_username="admin", | ||
vpc=vpc, | ||
multi_az=True, | ||
allocated_storage=100, | ||
storage_type=rds.StorageType.GP2, | ||
cloudwatch_logs_exports=["audit", "error", "general", "slowquery"], | ||
deletion_protection=False, | ||
delete_automated_backups=False, | ||
backup_retention=core.Duration.days(7), | ||
parameter_group=rds.ParameterGroup.from_parameter_group_name( | ||
self, "para-group-mysql", | ||
parameter_group_name="default.mysql5.7" | ||
) | ||
) | ||
for asg_sg in asg_security_groups: | ||
db_mysql_easy.connections.allow_default_port_from(asg_sg, "EC2 Autoscaling Group access MySQL") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from aws_cdk import core | ||
import aws_cdk.aws_ec2 as ec2 | ||
|
||
|
||
class CdkVpcStack(core.Stack): | ||
|
||
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: | ||
super().__init__(scope, id, **kwargs) | ||
|
||
# The code that defines your stack goes here | ||
|
||
self.vpc = ec2.Vpc(self, "VPC", | ||
max_azs=2, | ||
cidr="10.10.0.0/16", | ||
# configuration will create 3 groups in 2 AZs = 6 subnets. | ||
subnet_configuration=[ec2.SubnetConfiguration( | ||
subnet_type=ec2.SubnetType.PUBLIC, | ||
name="Public", | ||
cidr_mask=24 | ||
), ec2.SubnetConfiguration( | ||
subnet_type=ec2.SubnetType.PRIVATE, | ||
name="Private", | ||
cidr_mask=24 | ||
), ec2.SubnetConfiguration( | ||
subnet_type=ec2.SubnetType.ISOLATED, | ||
name="DB", | ||
cidr_mask=24 | ||
) | ||
], | ||
# nat_gateway_provider=ec2.NatProvider.gateway(), | ||
nat_gateways=2, | ||
) | ||
core.CfnOutput(self, "Output", | ||
value=self.vpc.vpc_id) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-e . |
Oops, something went wrong.