今日會使用CDK建立一樣的架構,如下圖:
在CDK可能有很多種不同的建立方式,這邊會介紹兩種,講述程式的開發流程。建置AWS的服務時,能畫出清晰的架構圖,撰寫或建置上都可以幫助完成需求。
本篇文章,專案名稱:ittest3,所以要撰寫AWS的服務,會在ittest3/ittest3_stack.py這個檔案建立。
在import library之前,需要先安裝套件,這樣才可以做使用。
一開始會需要import ec2,這樣在才有API可以去建置AWS EC2的服務。
from aws_cdk import (
aws_ec2 as ec2,
core
)
接下來就可以開始建立服務
這邊先建VPC,使用VScode IDE的好處,會有提示的功能,明確知道有提供哪些參數可以使用
myVPC = ec2.Vpc(self, "myVPC",
cidr="10.10.0.0/16",
enable_dns_hostnames=True,
enable_dns_support=True,
max_azs=1,
subnet_configuration=[
ec2.SubnetConfiguration(
name="public-subnet1",
subnet_type=ec2.SubnetType.PUBLIC,
cidr_mask=24
),
ec2.SubnetConfiguration(
name="public-subnet2",
subnet_type=ec2.SubnetType.PUBLIC,
cidr_mask=24
)
])
cidr:可以選擇private ip class A B C三種
https://zh.wikipedia.org/wiki/%E4%B8%93%E7%94%A8%E7%BD%91%E7%BB%9C
enable_dns_hostname & enable_dns_support:這兩個都是啟用dns hostname,這樣可以直接用dns訪問,不需要使用IP去訪問EC2
max_azs:這邊只有測試使用,只在一個AZ建立subnet,如果要達到HA,可以使用3個
subnet_configuration:這邊有格式上的不同,這個參數會需要List,所以在一開始有加上[],包覆整個function。SubnetConfiguration是這個參數支援的Type,這邊有使用蠻重要的三個參數。
name:區別subnet的名字,在建立EC2的時候可以去識別
subnet_type:架構圖是使用Public,所以這邊就使用Public的形式。還有Private和Isolated
cidr_mask:如果一開始沒有這個參數,系統會幫你建置,若後續想要建新的subnet,系統就會顯示錯誤,因為一開始建立的subnet占用。建議還是指定一個數字。
在建立EC2之前,需要先選擇OS。這裡使用Amazon Linux 2
ami = ec2.AmazonLinuxImage(cpu_type=ec2.AmazonLinuxCpuType.X86_64,
edition=ec2.AmazonLinuxEdition.STANDARD,
generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
virtualization=ec2.AmazonLinuxVirt.HVM
)
這邊會修改硬碟的類型,以及空間大小。預設是GP2,8GB
volume = ec2.BlockDevice(device_name="/dev/xvda",
volume=ec2.BlockDeviceVolume.ebs(volume_size=10,
volume_type=ec2.EbsDeviceVolumeType.GP3),
mapping_enabled=True)
device_name:硬碟要掛載的地方,root volume
在EC2設定SG以及inbound rules
mysg = ec2.SecurityGroup(self, "mySG",
vpc=myVPC,
allow_all_outbound=True,
description="CDK create security group",
security_group_name="ec2-sg1")
mysg.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(80))
mysg.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(22))
建立EC2,把上面的變數填進對應的參數。EC2都會有一把Key,這把Key是需要先建立好的
myec2 = ec2.Instance(self, "myEC2",
instance_type=ec2.InstanceType("t3.micro"),
machine_image=ami,
vpc=myVPC,
allow_all_outbound=True,
block_devices=[volume],
instance_name="myEC2",
key_name="itdemo",
security_group=mysg,
vpc_subnets=ec2.SubnetSelection(subnet_group_name="public-subnet1"),
user_data=ec2.UserData.custom(userdata),
)
block_devices:參數格式屬於List,所以有多加[]去轉換型態
vpc_subnets:上面VPC有設定subnet_configuration,所以會屬於同一個group。
user_data:第一次建立EC2會根據shell script去執行指令
with open("./ittest3/userdata.sh", "r", encoding="utf-8") as file:
userdata = file.read()
需要注意編碼問題
core.CfnOutput(self, "publicIP", value=myec2.instance_public_ip)
core.CfnOutput(self, "publicDNS", value=myec2.instance_public_dns_name)
core.CfnOutput(self, "privateIP", value=myec2.instance_private_ip)
core.CfnOutput(self, "privateDNS", value=myec2.instance_private_dns_name)
在VPC裡指定subnet_configuration,會自動建立subnet、route table和internet gateway,系統也會幫你設定subnet的CIDR,route table的路由方式,將internet gateway attach到VPC,可以快速的建立環境。
from aws_cdk import core as cdk
from aws_cdk import (
aws_ec2 as ec2,
core
)
with open("./ittest3/userdata.sh", "r", encoding="utf-8") as file:
userdata = file.read()
class Ittest3Stack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# The code that defines your stack goes here
myVPC = ec2.Vpc(self, "myVPC",
cidr="10.10.0.0/16",
enable_dns_hostnames=True,
enable_dns_support=True,
max_azs=1,
subnet_configuration=[
ec2.SubnetConfiguration(
name="public-subnet1",
subnet_type=ec2.SubnetType.PUBLIC,
cidr_mask=24
),
ec2.SubnetConfiguration(
name="public-subnet2",
subnet_type=ec2.SubnetType.PUBLIC,
cidr_mask=24
)
])
ami = ec2.AmazonLinuxImage(cpu_type=ec2.AmazonLinuxCpuType.X86_64,
edition=ec2.AmazonLinuxEdition.STANDARD,
generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
virtualization=ec2.AmazonLinuxVirt.HVM
)
volume = ec2.BlockDevice(device_name="/dev/xvda",
volume=ec2.BlockDeviceVolume.ebs(volume_size=10,
volume_type=ec2.EbsDeviceVolumeType.GP3),
mapping_enabled=True)
mysg = ec2.SecurityGroup(self, "mySG",
vpc=myVPC,
allow_all_outbound=True,
description="CDK create security group",
security_group_name="ec2-sg1")
mysg.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(80))
mysg.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(22))
myec2 = ec2.Instance(self, "myEC2",
instance_type=ec2.InstanceType("t3.micro"),
machine_image=ami,
vpc=myVPC,
allow_all_outbound=True,
block_devices=[volume],
instance_name="myEC2",
key_name="itdemo",
security_group=mysg,
vpc_subnets=ec2.SubnetSelection(subnet_group_name="public-subnet1"),
user_data=ec2.UserData.custom(userdata),
)
core.CfnOutput(self, "publicIP", value=myec2.instance_public_ip)
core.CfnOutput(self, "publicDNS", value=myec2.instance_public_dns_name)
core.CfnOutput(self, "privateIP", value=myec2.instance_private_ip)
core.CfnOutput(self, "privateDNS", value=myec2.instance_private_dns_name)