只要有vscode和python就可以享受AWS上的服务

轻松快速道路

今日会使用CDK建立一样的架构,如下图:
https://ithelp.ithome.com.tw/upload/images/20210928/20140172ynk5mFfJUA.png
在CDK可能有很多种不同的建立方式,这边会介绍两种,讲述程序的开发流程。建置AWS的服务时,能画出清晰的架构图,撰写或建置上都可以帮助完成需求。

本篇文章,专案名称:ittest3,所以要撰写AWS的服务,会在ittest3/ittest3_stack.py这个档案建立。

在import library之前,需要先安装套件,这样才可以做使用。
https://ithelp.ithome.com.tw/upload/images/20210928/20140172WCpuHtSPJA.png
一开始会需要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占用。建议还是指定一个数字。
https://ithelp.ithome.com.tw/upload/images/20210928/20140172YKYg3r6NvR.png
在建立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)

部属

https://ithelp.ithome.com.tw/upload/images/20210928/20140172MTWAZ7aBTZ.png

结果

https://ithelp.ithome.com.tw/upload/images/20210928/20140172ScrAFRcxHB.png
https://ithelp.ithome.com.tw/upload/images/20210928/20140172fLHtJSw7Nf.png

移除资源

https://ithelp.ithome.com.tw/upload/images/20210928/20140172D8jzB6xLgV.png

结论

在VPC里指定subnet_configuration,会自动建立subnet、route table和internet gateway,系统也会帮你设定subnet的CIDR,route table的路由方式,将internet gateway attach到VPC,可以快速的建立环境。
https://ithelp.ithome.com.tw/upload/images/20210928/20140172INyD5R8GkD.png

完整程序码

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)

<<:  [Day13]ISO 27001 标准:风险评监

>>:  [Android Studio 30天自我挑战] Progress Bar练习2

[Day21] 扩展你的设计:根据与对话发生的装置修改对白

从手机到智慧音箱,在不同装置上要考量到的情形皆有差异。 这篇文章中将先介绍Google助理可回应的...

[CSS] Flex/Grid Layout Modules, part 13

单元对齐跟留白的部分今天会继续,定位的问题基本上不出乱子的话就如同昨天说明的。当然,如果再加上对齐跟...

C# 入门之访问修饰符(补充)

写了一大半,发现写崩了,前面有很多东西没有写到,这两天会添加一些补充的内容。 今天我们首先来看一下 ...

[Day7] 用 Python 实作 VAR 多变量时间序列预测

Hey guys, 第七篇就来实作一遍,「以传统统计方法」预测多变量时间序列吧 虽然 VAR 的准确...

Day 19 - 网页元素DOM - 表单元件的Event,表单的type 设定

制作表单 createRadio(); 沿用上一个文章的参考 加上以下设定 我们可以用radio去做...