iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
DevOps

從煉獄走到天堂的AWS DevOps 工具及應用開發大進擊系列 第 14

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

  • 分享至 

  • xImage
  •  

輕鬆快速道路

今日會使用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)

上一篇
選擇寫程式的路,在AWS上先躲開可能會遇到的地雷區
下一篇
透過寫程式可以更熟悉AWS console上的完整操作
系列文
從煉獄走到天堂的AWS DevOps 工具及應用開發大進擊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言