「Boosting MySQL database performance with Amazon ElastiCache for Redis」をAWS CLIでやってみる

https://aws.amazon.com/jp/getting-started/hands-on/boosting-mysql-database-performance-with-amazon-elasticache-for-redis/

上記、「ABoosting MySQL database performance with Amazon ElastiCache for Redis」 をAWS CLIでやってみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3297641/5998e860-8ee6-6548-fb79-36abd0aced18.png)
ハンズオンから引用

:::note warn
<INS>**CloudShellから実施**</INS>
CloudShellはタブを２つ使用
タブ１：AWS構築用
タブ２：EC2操作用 (Session Manager接続)
:::
# 事前作業
## VPC作成 (タブ1)
:::note info
ハンズオン用のVPCを作成
:::
### 変数
```bash:コマンド
# VPC名
VPC_NAME="handson-vpc" \
&& echo ${VPC_NAME}

# サブネット名
SUBNET_NAME_0="handson-pub-1a" \
&& echo ${SUBNET_NAME_1}

SUBNET_NAME_1="handson-pri-1a" \
&& echo ${SUBNET_NAME_1}

SUBNET_NAME_2="handson-pri-1c" \
&& echo ${SUBNET_NAME_2}

SUBNET_NAME_3="handson-pri-1d" \
&& echo ${SUBNET_NAME_3}

# VPC CIDR block
VPC_CIDR_BLOCK="10.0.0.0/16" \
&& echo ${VPC_CIDR_BLOCK}

# サブネット CIDR block
CIDR_BLOCK_0="10.0.0.0/24" \
&& echo ${CIDR_BLOCK_0}

CIDR_BLOCK_1="10.0.1.0/24" \
&& echo ${CIDR_BLOCK_1}

CIDR_BLOCK_2="10.0.2.0/24" \
&& echo ${CIDR_BLOCK_2}

CIDR_BLOCK_3="10.0.3.0/24" \
&& echo ${CIDR_BLOCK_3}

# アベイラビリティーゾーン
AZ_1="ap-northeast-1a" \
&& echo ${AZ_1}

AZ_2="ap-northeast-1c" \
&& echo ${AZ_1}

AZ_3="ap-northeast-1d" \
&& echo ${AZ_1}

# インターネットゲートウェイ名
IGW_NAME='handson-igw' \
&& echo ${IGW_NAME}

# ルートテーブル名
RT_NAME='Public Route Table' \
&& echo ${RT_NAME}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # VPC名
[cloudshell-user@ip-10-132-66-29 ~]$ VPC_NAME="handson-vpc" \
> && echo ${VPC_NAME}
handson-vpc
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネット名
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_NAME_0="handson-pub-1a" \
> && echo ${SUBNET_NAME_1}
handson-pri-1a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_NAME_1="handson-pri-1a" \
> && echo ${SUBNET_NAME_1}
handson-pri-1a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_NAME_2="handson-pri-1c" \
> && echo ${SUBNET_NAME_2}
handson-pri-1c
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_NAME_3="handson-pri-1d" \
> && echo ${SUBNET_NAME_3}
handson-pri-1d
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # VPC CIDR block
[cloudshell-user@ip-10-132-66-29 ~]$ VPC_CIDR_BLOCK="10.0.0.0/16" \
> && echo ${VPC_CIDR_BLOCK}
10.0.0.0/16
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネット CIDR block
[cloudshell-user@ip-10-132-66-29 ~]$ CIDR_BLOCK_0="10.0.0.0/24" \
> && echo ${CIDR_BLOCK_0}
10.0.0.0/24
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ CIDR_BLOCK_1="10.0.1.0/24" \
> && echo ${CIDR_BLOCK_1}
10.0.1.0/24
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ CIDR_BLOCK_2="10.0.2.0/24" \
> && echo ${CIDR_BLOCK_2}
10.0.2.0/24
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ CIDR_BLOCK_3="10.0.3.0/24" \
> && echo ${CIDR_BLOCK_3}
10.0.3.0/24
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # アベイラビリティーゾーン
[cloudshell-user@ip-10-132-66-29 ~]$ AZ_1="ap-northeast-1a" \
> && echo ${AZ_1}
ap-northeast-1a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ AZ_2="ap-northeast-1c" \
> && echo ${AZ_1}
ap-northeast-1a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ AZ_3="ap-northeast-1d" \
> && echo ${AZ_1}
ap-northeast-1a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイ名
[cloudshell-user@ip-10-132-66-29 ~]$ IGW_NAME='handson-igw' \
> && echo ${IGW_NAME}
handson-igw
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ルートテーブル名
[cloudshell-user@ip-10-132-66-29 ~]$ RT_NAME='Public Route Table' \
> && echo ${RT_NAME}
Public Route Table
```
### VPC作成
```bash:コマンド
# VPC作成
aws ec2 create-vpc \
    --cidr-block ${VPC_CIDR_BLOCK} \
    --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=${VPC_NAME}}]"

# VPC ID取得
VPC_ID=$(
    aws ec2 describe-vpcs \
        --filters "Name=tag:Name,Values=${VPC_NAME}" \
        --query "Vpcs[].VpcId" \
        --output text
)\
&& echo ${VPC_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # VPC作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-vpc \
>     --cidr-block ${VPC_CIDR_BLOCK} \
>     --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=${VPC_NAME}}]"
{
    "Vpc": {
        "CidrBlock": "10.0.0.0/16",
        "DhcpOptionsId": "dopt-0e7d97fbb33a62ce1",
        "State": "pending",
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999",
        "InstanceTenancy": "default",
        "Ipv6CidrBlockAssociationSet": [],
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-02a0380c98f2c253c",
                "CidrBlock": "10.0.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "IsDefault": false,
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-vpc"
            }
        ]
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # VPC ID取得
[cloudshell-user@ip-10-132-66-29 ~]$ VPC_ID=$(
>     aws ec2 describe-vpcs \
>         --filters "Name=tag:Name,Values=${VPC_NAME}" \
>         --query "Vpcs[].VpcId" \
>         --output text
> )\
> && echo ${VPC_ID}
vpc-02f245097860e1f1c
```
### サブネット作成
```bash:コマンド
# サブネット作成
aws ec2 create-subnet \
    --vpc-id ${VPC_ID} \
    --cidr-block ${CIDR_BLOCK_0} \
    --availability-zone ${AZ_1} \
    --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_0}}]"

aws ec2 create-subnet \
    --vpc-id ${VPC_ID} \
    --cidr-block ${CIDR_BLOCK_1} \
    --availability-zone ${AZ_1} \
    --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_1}}]"

aws ec2 create-subnet \
    --vpc-id ${VPC_ID} \
    --cidr-block ${CIDR_BLOCK_2} \
    --availability-zone ${AZ_2} \
    --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_2}}]"

aws ec2 create-subnet \
    --vpc-id ${VPC_ID} \
    --cidr-block ${CIDR_BLOCK_3} \
    --availability-zone ${AZ_3} \
    --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_3}}]"

# サブネットID取得
SUBNET_ID_0=$(
    aws ec2 describe-subnets \
      --filters Name=vpc-id,Values=${VPC_ID} \
                Name=tag:Name,Values="${SUBNET_NAME_0}" \
      --query "Subnets[].SubnetId" \
      --output text
) \
&& echo ${SUBNET_ID_0}

SUBNET_ID_1=$(
    aws ec2 describe-subnets \
      --filters Name=vpc-id,Values=${VPC_ID} \
                Name=tag:Name,Values="${SUBNET_NAME_1}" \
      --query "Subnets[].SubnetId" \
      --output text
) \
&& echo ${SUBNET_ID_1}

SUBNET_ID_2=$(
    aws ec2 describe-subnets \
      --filters Name=vpc-id,Values=${VPC_ID} \
                Name=tag:Name,Values="${SUBNET_NAME_2}" \
      --query "Subnets[].SubnetId" \
      --output text
) \
&& echo ${SUBNET_ID_2}

SUBNET_ID_3=$(
    aws ec2 describe-subnets \
      --filters Name=vpc-id,Values=${VPC_ID} \
                Name=tag:Name,Values="${SUBNET_NAME_3}" \
      --query "Subnets[].SubnetId" \
      --output text
) \
&& echo ${SUBNET_ID_3}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネット作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-subnet \
>     --vpc-id ${VPC_ID} \
>     --cidr-block ${CIDR_BLOCK_0} \
>     --availability-zone ${AZ_1} \
>     --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_0}}]"
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1a",
        "AvailabilityZoneId": "apne1-az4",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "10.0.0.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-0f810913fe25bbf0a",
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-pub-1a"
            }
        ],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:999999999999:subnet/subnet-0f810913fe25bbf0a",
        "EnableDns64": false,
        "Ipv6Native": false,
        "PrivateDnsNameOptionsOnLaunch": {
            "HostnameType": "ip-name",
            "EnableResourceNameDnsARecord": false,
            "EnableResourceNameDnsAAAARecord": false
        }
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-subnet \
>     --vpc-id ${VPC_ID} \
>     --cidr-block ${CIDR_BLOCK_1} \
>     --availability-zone ${AZ_1} \
>     --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_1}}]"
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1a",
        "AvailabilityZoneId": "apne1-az4",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "10.0.1.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-0963cc13256b4e3f6",
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-pri-1a"
            }
        ],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:999999999999:subnet/subnet-0963cc13256b4e3f6",
        "EnableDns64": false,
        "Ipv6Native": false,
        "PrivateDnsNameOptionsOnLaunch": {
            "HostnameType": "ip-name",
            "EnableResourceNameDnsARecord": false,
            "EnableResourceNameDnsAAAARecord": false
        }
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-subnet \
>     --vpc-id ${VPC_ID} \
>     --cidr-block ${CIDR_BLOCK_2} \
>     --availability-zone ${AZ_2} \
>     --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_2}}]"
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1c",
        "AvailabilityZoneId": "apne1-az1",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "10.0.2.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-0834139fed8def7d4",
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-pri-1c"
            }
        ],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:999999999999:subnet/subnet-0834139fed8def7d4",
        "EnableDns64": false,
        "Ipv6Native": false,
        "PrivateDnsNameOptionsOnLaunch": {
            "HostnameType": "ip-name",
            "EnableResourceNameDnsARecord": false,
            "EnableResourceNameDnsAAAARecord": false
        }
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-subnet \
>     --vpc-id ${VPC_ID} \
>     --cidr-block ${CIDR_BLOCK_3} \
>     --availability-zone ${AZ_3} \
>     --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=${SUBNET_NAME_3}}]"
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1d",
        "AvailabilityZoneId": "apne1-az2",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "10.0.3.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-08c662c844ea24a8c",
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-pri-1d"
            }
        ],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:999999999999:subnet/subnet-08c662c844ea24a8c",
        "EnableDns64": false,
        "Ipv6Native": false,
        "PrivateDnsNameOptionsOnLaunch": {
            "HostnameType": "ip-name",
            "EnableResourceNameDnsARecord": false,
            "EnableResourceNameDnsAAAARecord": false
        }
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネットID取得
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_ID_0=$(
>     aws ec2 describe-subnets \
>       --filters Name=vpc-id,Values=${VPC_ID} \
>                 Name=tag:Name,Values="${SUBNET_NAME_0}" \
>       --query "Subnets[].SubnetId" \
>       --output text
> ) \
> && echo ${SUBNET_ID_0}
subnet-0f810913fe25bbf0a
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_ID_1=$(
>     aws ec2 describe-subnets \
>       --filters Name=vpc-id,Values=${VPC_ID} \
>                 Name=tag:Name,Values="${SUBNET_NAME_1}" \
>       --query "Subnets[].SubnetId" \
>       --output text
> ) \
> && echo ${SUBNET_ID_1}
subnet-0963cc13256b4e3f6
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_ID_2=$(
>     aws ec2 describe-subnets \
>       --filters Name=vpc-id,Values=${VPC_ID} \
>                 Name=tag:Name,Values="${SUBNET_NAME_2}" \
>       --query "Subnets[].SubnetId" \
>       --output text
> ) \
> && echo ${SUBNET_ID_2}
subnet-0834139fed8def7d4
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ SUBNET_ID_3=$(
>     aws ec2 describe-subnets \
>       --filters Name=vpc-id,Values=${VPC_ID} \
>                 Name=tag:Name,Values="${SUBNET_NAME_3}" \
>       --query "Subnets[].SubnetId" \
>       --output text
> ) \
> && echo ${SUBNET_ID_3}
subnet-08c662c844ea24a8c
```
### インターネットゲートウェイ作成
```bash:コマンド
# インターネットゲートウェイ作成
aws ec2 create-internet-gateway \
    --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Name,Value=${IGW_NAME}}]"

# インターネットゲートウェイID取得
IGW_ID=$(
    aws ec2 describe-internet-gateways \
        --filters Name=tag:Name,Values=${IGW_NAME} \
        --query "InternetGateways[].InternetGatewayId" \
        --output text
) \
&& echo ${IGW_ID}

# インターネットゲートウェイをVPCにアタッチ
aws ec2 attach-internet-gateway \
    --vpc-id ${VPC_ID} \
    --internet-gateway-id ${IGW_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイ作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-internet-gateway \
>     --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=Name,Value=${IGW_NAME}}]"
{
    "InternetGateway": {
        "Attachments": [],
        "InternetGatewayId": "igw-0dcb7636070161845",
        "OwnerId": "999999999999",
        "Tags": [
            {
                "Key": "Name",
                "Value": "handson-igw"
            }
        ]
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイID取得
[cloudshell-user@ip-10-132-66-29 ~]$ IGW_ID=$(
>     aws ec2 describe-internet-gateways \
>         --filters Name=tag:Name,Values=${IGW_NAME} \
>         --query "InternetGateways[].InternetGatewayId" \
>         --output text
> ) \
> && echo ${IGW_ID}
igw-0dcb7636070161845
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイをVPCにアタッチ
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 attach-internet-gateway \
>     --vpc-id ${VPC_ID} \
>     --internet-gateway-id ${IGW_ID}
```
### ルートテーブル作成
```bash:コマンド
# ルートテーブル作成
aws ec2 create-route-table \
    --vpc-id ${VPC_ID} \
    --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=${RT_NAME}}]"

# ルートテーブルID取得
RT_ID=$(
    aws ec2 describe-route-tables \
        --filters Name=vpc-id,Values=${VPC_ID} \
                  Name=tag:Name,Values="${RT_NAME}" \
        --query "RouteTables[].RouteTableId" \
        --output text
) \
&& echo ${RT_ID}

# デフォルトルート作成
aws ec2 create-route \
    --route-table-id ${RT_ID} \
    --destination-cidr-block 0.0.0.0/0 \
    --gateway-id ${IGW_ID}

# サブネット関連付け
aws ec2 associate-route-table \
    --subnet-id ${SUBNET_ID_0} \
    --route-table-id ${RT_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # ルートテーブル作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-route-table \
>     --vpc-id ${VPC_ID} \
>     --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=${RT_NAME}}]"
{
    "RouteTable": {
        "Associations": [],
        "PropagatingVgws": [],
        "RouteTableId": "rtb-0b4797f379c71e7ba",
        "Routes": [
            {
                "DestinationCidrBlock": "10.0.0.0/16",
                "GatewayId": "local",
                "Origin": "CreateRouteTable",
                "State": "active"
            }
        ],
        "Tags": [
            {
                "Key": "Name",
                "Value": "Public Route Table"
            }
        ],
        "VpcId": "vpc-02f245097860e1f1c",
        "OwnerId": "999999999999"
    },
    "ClientToken": "25968a2d-57ee-4145-bac7-31867cc6b268"
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ルートテーブルID取得
[cloudshell-user@ip-10-132-66-29 ~]$ RT_ID=$(
>     aws ec2 describe-route-tables \
>         --filters Name=vpc-id,Values=${VPC_ID} \
>                   Name=tag:Name,Values="${RT_NAME}" \
>         --query "RouteTables[].RouteTableId" \
>         --output text
> ) \
> && echo ${RT_ID}
rtb-0b4797f379c71e7ba
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # デフォルトルート作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-route \
>     --route-table-id ${RT_ID} \
>     --destination-cidr-block 0.0.0.0/0 \
>     --gateway-id ${IGW_ID}
{
    "Return": true
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネット関連付け
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 associate-route-table \
>     --subnet-id ${SUBNET_ID_0} \
>     --route-table-id ${RT_ID}
{
    "AssociationId": "rtbassoc-0c541e8367520cbec",
    "AssociationState": {
        "State": "associated"
    }
}
```
## IAM関連の準備 (タブ1)
### 変数
```bash:コマンド
# IAMロール名
IAM_ROLE_NAME="handson-ec2-role" \
&& echo ${IAM_ROLE_NAME}

# アタッチポリシー名
IAM_ATTACH_POLICY_NAME="AmazonSSMManagedInstanceCore" \
&& echo ${IAM_ATTACH_POLICY_NAME}

# アタッチポリシーARN
IAM_POLICY_ARN="arn:aws:iam::aws:policy/${IAM_ATTACH_POLICY_NAME}" \
&& echo ${IAM_POLICY_ARN}

# インスタンスプロファイル名
IAM_INSTANCE_PROFILE_NAME="handson-ec2-profile" \
&& echo ${IAM_INSTANCE_PROFILE_NAME}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # IAMロール名
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_ROLE_NAME="handson-ec2-role" \
> && echo ${IAM_ROLE_NAME}
handson-ec2-role
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # アタッチポリシー名
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_ATTACH_POLICY_NAME="AmazonSSMManagedInstanceCore" \
> && echo ${IAM_ATTACH_POLICY_NAME}
AmazonSSMManagedInstanceCore
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # アタッチポリシーARN
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_POLICY_ARN="arn:aws:iam::aws:policy/${IAM_ATTACH_POLICY_NAME}" \
> && echo ${IAM_POLICY_ARN}
arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスプロファイル名
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_INSTANCE_PROFILE_NAME="handson-ec2-profile" \
> && echo ${IAM_INSTANCE_PROFILE_NAME}
handson-ec2-profile
```
### IAMロールの作成
```bash:コマンド
# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --role-name ${IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${IAM_ROLE_NAME} \
        --query 'Role.Arn' \
        --output text
) \
&& echo ${IAM_ROLE_ARN}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-66-29 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "ec2.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-66-29 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam create-role \
>     --role-name ${IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/",
        "RoleName": "handson-ec2-role",
        "RoleId": "AROAWFKRCMKOUS6HINRLE",
        "Arn": "arn:aws:iam::999999999999:role/handson-ec2-role",
        "CreateDate": "2024-08-18T05:07:08+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ARN取得
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${IAM_ROLE_NAME} \
>         --query 'Role.Arn' \
>         --output text
> ) \
> && echo ${IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/handson-ec2-role
```
### IAMポリシーのアタッチ
```bash:コマンド
# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${IAM_ROLE_NAME} \
    --policy-arn ${IAM_POLICY_ARN}

# インスタンスプロファイル作成
aws iam create-instance-profile \
    --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}

# インスタンスプロファイルへのロールのアタッチ
aws iam add-role-to-instance-profile \
    --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} \
    --role-name ${IAM_ROLE_NAME}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam attach-role-policy \
>     --role-name ${IAM_ROLE_NAME} \
>     --policy-arn ${IAM_POLICY_ARN}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスプロファイル作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam create-instance-profile \
>     --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}
{
    "InstanceProfile": {
        "Path": "/",
        "InstanceProfileName": "handson-ec2-profile",
        "InstanceProfileId": "AIPAWFKRCMKOUQHQDQ23P",
        "Arn": "arn:aws:iam::999999999999:instance-profile/handson-ec2-profile",
        "CreateDate": "2024-08-18T05:08:03+00:00",
        "Roles": []
    }
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスプロファイルへのロールのアタッチ
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam add-role-to-instance-profile \
>     --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} \
>     --role-name ${IAM_ROLE_NAME}
```
## EC2の作成 (タブ1)
### 変数
```bash:コマンド
# 名前
EC2_NAME="handson-ec2" \
&& echo ${EC2_NAME}

# インスタンスタイプ
EC2_INSTANCE_TYPE="t2.micro" \
&& echo ${EC2_INSTANCE_TYPE}

# Amazon マシンイメージ (AMI)
EC2_IMAGE_ID="resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64" \
&& echo ${EC2_IMAGE_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # 名前
[cloudshell-user@ip-10-132-66-29 ~]$ EC2_NAME="handson-ec2" \
> && echo ${EC2_NAME}
handson-ec2
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-132-66-29 ~]$ EC2_INSTANCE_TYPE="t2.micro" \
> && echo ${EC2_INSTANCE_TYPE}
t2.micro
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # Amazon マシンイメージ (AMI)
[cloudshell-user@ip-10-132-66-29 ~]$ EC2_IMAGE_ID="resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64" \
> && echo ${EC2_IMAGE_ID}
resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
```
### EC2作成
```bash:コマンド
# EC2インスタンス作成
aws ec2 run-instances \
    --image-id ${EC2_IMAGE_ID} \
    --instance-type ${EC2_INSTANCE_TYPE} \
    --associate-public-ip-address \
    --subnet-id ${SUBNET_ID_0} \
    --iam-instance-profile Name=${IAM_INSTANCE_PROFILE_NAME} \
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${EC2_NAME}}]" \
    --no-cli-pager

# インスタンスID
EC2_INSTANCE_ID=$( \
    aws ec2 describe-instances \
        --filters Name=tag:Name,Values=${EC2_NAME}  \
        --query "Reservations[*].Instances[*].[InstanceId]" \
        --output text
) \
&& echo ${EC2_INSTANCE_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # EC2インスタンス作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 run-instances \
>     --image-id ${EC2_IMAGE_ID} \
>     --instance-type ${EC2_INSTANCE_TYPE} \
>     --associate-public-ip-address \
>     --subnet-id ${SUBNET_ID_0} \
>     --iam-instance-profile Name=${IAM_INSTANCE_PROFILE_NAME} \
>     --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${EC2_NAME}}]" \
>     --no-cli-pager
{
    "Groups": [],
    "Instances": [
        {
            "AmiLaunchIndex": 0,
            "ImageId": "ami-0091f05e4b8ee6709",
            "InstanceId": "i-0fc8f94dd973f6300",
            "InstanceType": "t2.micro",
            "LaunchTime": "2024-08-18T05:15:06+00:00",
            "Monitoring": {
                "State": "disabled"
            },
            "Placement": {
                "AvailabilityZone": "ap-northeast-1a",
                "GroupName": "",
                "Tenancy": "default"
            },
            "PrivateDnsName": "ip-10-0-0-17.ap-northeast-1.compute.internal",
            "PrivateIpAddress": "10.0.0.17",
            "ProductCodes": [],
            "PublicDnsName": "",
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "StateTransitionReason": "",
            "SubnetId": "subnet-0f810913fe25bbf0a",
            "VpcId": "vpc-02f245097860e1f1c",
            "Architecture": "x86_64",
            "BlockDeviceMappings": [],
            "ClientToken": "67a16e40-6ed8-4909-88e0-bf722b2e06bf",
            "EbsOptimized": false,
            "EnaSupport": true,
            "Hypervisor": "xen",
            "IamInstanceProfile": {
                "Arn": "arn:aws:iam::999999999999:instance-profile/handson-ec2-profile",
                "Id": "AIPAWFKRCMKOUQHQDQ23P"
            },
            "NetworkInterfaces": [
                {
                    "Attachment": {
                        "AttachTime": "2024-08-18T05:15:06+00:00",
                        "AttachmentId": "eni-attach-0e3bd8a9ec2d66eef",
                        "DeleteOnTermination": true,
                        "DeviceIndex": 0,
                        "Status": "attaching",
                        "NetworkCardIndex": 0
                    },
                    "Description": "",
                    "Groups": [
                        {
                            "GroupName": "default",
                            "GroupId": "sg-09be7f68d1d65d8f9"
                        }
                    ],
                    "Ipv6Addresses": [],
                    "MacAddress": "06:62:0d:ec:be:a7",
                    "NetworkInterfaceId": "eni-0f63801f990d7357d",
                    "OwnerId": "999999999999",
                    "PrivateIpAddress": "10.0.0.17",
                    "PrivateIpAddresses": [
                        {
                            "Primary": true,
                            "PrivateIpAddress": "10.0.0.17"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Status": "in-use",
                    "SubnetId": "subnet-0f810913fe25bbf0a",
                    "VpcId": "vpc-02f245097860e1f1c",
                    "InterfaceType": "interface"
                }
            ],
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SecurityGroups": [
                {
                    "GroupName": "default",
                    "GroupId": "sg-09be7f68d1d65d8f9"
                }
            ],
            "SourceDestCheck": true,
            "StateReason": {
                "Code": "pending",
                "Message": "pending"
            },
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "handson-ec2"
                }
            ],
            "VirtualizationType": "hvm",
            "CpuOptions": {
                "CoreCount": 1,
                "ThreadsPerCore": 1
            },
            "CapacityReservationSpecification": {
                "CapacityReservationPreference": "open"
            },
            "MetadataOptions": {
                "State": "pending",
                "HttpTokens": "required",
                "HttpPutResponseHopLimit": 2,
                "HttpEndpoint": "enabled",
                "HttpProtocolIpv6": "disabled",
                "InstanceMetadataTags": "disabled"
            },
            "EnclaveOptions": {
                "Enabled": false
            },
            "BootMode": "uefi-preferred",
            "PrivateDnsNameOptions": {
                "HostnameType": "ip-name",
                "EnableResourceNameDnsARecord": false,
                "EnableResourceNameDnsAAAARecord": false
            },
            "MaintenanceOptions": {
                "AutoRecovery": "default"
            },
            "CurrentInstanceBootMode": "legacy-bios"
        }
    ],
    "OwnerId": "999999999999",
    "ReservationId": "r-0e1ee3a3751d680f4"
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスID
[cloudshell-user@ip-10-132-66-29 ~]$ EC2_INSTANCE_ID=$( \
>     aws ec2 describe-instances \
>         --filters Name=tag:Name,Values=${EC2_NAME}  \
>         --query "Reservations[*].Instances[*].[InstanceId]" \
>         --output text
> ) \
> && echo ${EC2_INSTANCE_ID}
i-0fc8f94dd973f6300
```
## Python環境 (タブ1)
### Session Managerを使ったサーバログイン (タブ2)
:::note warn
EC2_INSTANCE_IDは適宜変更
:::
```bash:コマンド
EC2_INSTANCE_ID=i-0fc8f94dd973f6300

aws ssm start-session \
    --target ${EC2_INSTANCE_ID} 

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ EC2_INSTANCE_ID=i-0fc8f94dd973f6300
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ aws ssm start-session \
>     --target ${EC2_INSTANCE_ID} 

Starting session with SessionId: admin-jdj2onl4uro4m7nc63qa57oesu
sh-5.2$ 
```
### Pythonインストール
```bash:コマンド
cd ~
sudo dnf install git -y
sudo dnf install mariadb105 -y
git clone https://github.com/aws-samples/amazon-elasticache-samples/
cd amazon-elasticache-samples/database-caching
python3 -m venv venv
source ./venv/bin/activate
pip3 install -r requirements.txt

```
```bash:出力
sh-5.2$ cd ~
sh-5.2$ sudo dnf install git -y
Last metadata expiration check: 0:04:48 ago on Sun Aug 18 05:15:58 2024.
Dependencies resolved.
===========================================================================================================================================================================================================================================================================================
 Package                                                               Architecture                                                Version                                                                          Repository                                                        Size
===========================================================================================================================================================================================================================================================================================
Installing:
 git                                                                   x86_64                                                      2.40.1-1.amzn2023.0.3                                                            amazonlinux                                                       54 k
Installing dependencies:
 git-core                                                              x86_64                                                      2.40.1-1.amzn2023.0.3                                                            amazonlinux                                                      4.3 M
 git-core-doc                                                          noarch                                                      2.40.1-1.amzn2023.0.3                                                            amazonlinux                                                      2.6 M
 perl-Error                                                            noarch                                                      1:0.17029-5.amzn2023.0.2                                                         amazonlinux                                                       41 k
 perl-File-Find                                                        noarch                                                      1.37-477.amzn2023.0.6                                                            amazonlinux                                                       26 k
 perl-Git                                                              noarch                                                      2.40.1-1.amzn2023.0.3                                                            amazonlinux                                                       42 k
 perl-TermReadKey                                                      x86_64                                                      2.38-9.amzn2023.0.2                                                              amazonlinux                                                       36 k
 perl-lib                                                              x86_64                                                      0.65-477.amzn2023.0.6                                                            amazonlinux                                                       15 k

Transaction Summary
===========================================================================================================================================================================================================================================================================================
Install  8 Packages

Total download size: 7.1 M
Installed size: 34 M
Downloading Packages:
(1/8): git-2.40.1-1.amzn2023.0.3.x86_64.rpm                                                                                                                                                                                                                723 kB/s |  54 kB     00:00    
(2/8): perl-Error-0.17029-5.amzn2023.0.2.noarch.rpm                                                                                                                                                                                                        965 kB/s |  41 kB     00:00    
(3/8): perl-File-Find-1.37-477.amzn2023.0.6.noarch.rpm                                                                                                                                                                                                     858 kB/s |  26 kB     00:00    
(4/8): git-core-doc-2.40.1-1.amzn2023.0.3.noarch.rpm                                                                                                                                                                                                        14 MB/s | 2.6 MB     00:00    
(5/8): perl-Git-2.40.1-1.amzn2023.0.3.noarch.rpm                                                                                                                                                                                                           976 kB/s |  42 kB     00:00    
(6/8): perl-lib-0.65-477.amzn2023.0.6.x86_64.rpm                                                                                                                                                                                                           514 kB/s |  15 kB     00:00    
(7/8): perl-TermReadKey-2.38-9.amzn2023.0.2.x86_64.rpm                                                                                                                                                                                                     989 kB/s |  36 kB     00:00    
(8/8): git-core-2.40.1-1.amzn2023.0.3.x86_64.rpm                                                                                                                                                                                                            12 MB/s | 4.3 MB     00:00    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                                       16 MB/s | 7.1 MB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                                                                                                                   1/1 
  Installing       : git-core-2.40.1-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                             1/8 
  Installing       : git-core-doc-2.40.1-1.amzn2023.0.3.noarch                                                                                                                                                                                                                         2/8 
  Installing       : perl-lib-0.65-477.amzn2023.0.6.x86_64                                                                                                                                                                                                                             3/8 
  Installing       : perl-TermReadKey-2.38-9.amzn2023.0.2.x86_64                                                                                                                                                                                                                       4/8 
  Installing       : perl-File-Find-1.37-477.amzn2023.0.6.noarch                                                                                                                                                                                                                       5/8 
  Installing       : perl-Error-1:0.17029-5.amzn2023.0.2.noarch                                                                                                                                                                                                                        6/8 
  Installing       : perl-Git-2.40.1-1.amzn2023.0.3.noarch                                                                                                                                                                                                                             7/8 
  Installing       : git-2.40.1-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                                  8/8 
  Running scriptlet: git-2.40.1-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                                  8/8 
  Verifying        : git-2.40.1-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                                  1/8 
  Verifying        : git-core-2.40.1-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                             2/8 
  Verifying        : git-core-doc-2.40.1-1.amzn2023.0.3.noarch                                                                                                                                                                                                                         3/8 
  Verifying        : perl-Error-1:0.17029-5.amzn2023.0.2.noarch                                                                                                                                                                                                                        4/8 
  Verifying        : perl-File-Find-1.37-477.amzn2023.0.6.noarch                                                                                                                                                                                                                       5/8 
  Verifying        : perl-Git-2.40.1-1.amzn2023.0.3.noarch                                                                                                                                                                                                                             6/8 
  Verifying        : perl-TermReadKey-2.38-9.amzn2023.0.2.x86_64                                                                                                                                                                                                                       7/8 
  Verifying        : perl-lib-0.65-477.amzn2023.0.6.x86_64                                                                                                                                                                                                                             8/8 

Installed:
  git-2.40.1-1.amzn2023.0.3.x86_64                 git-core-2.40.1-1.amzn2023.0.3.x86_64      git-core-doc-2.40.1-1.amzn2023.0.3.noarch      perl-Error-1:0.17029-5.amzn2023.0.2.noarch      perl-File-Find-1.37-477.amzn2023.0.6.noarch      perl-Git-2.40.1-1.amzn2023.0.3.noarch     
  perl-TermReadKey-2.38-9.amzn2023.0.2.x86_64      perl-lib-0.65-477.amzn2023.0.6.x86_64     

Complete!
sh-5.2$ sudo dnf install mariadb105 -y
Last metadata expiration check: 0:05:03 ago on Sun Aug 18 05:15:58 2024.
Dependencies resolved.
===========================================================================================================================================================================================================================================================================================
 Package                                                                       Architecture                                              Version                                                                      Repository                                                      Size
===========================================================================================================================================================================================================================================================================================
Installing:
 mariadb105                                                                    x86_64                                                    3:10.5.25-1.amzn2023.0.1                                                     amazonlinux                                                    1.6 M
Installing dependencies:
 mariadb-connector-c                                                           x86_64                                                    3.1.13-1.amzn2023.0.3                                                        amazonlinux                                                    196 k
 mariadb-connector-c-config                                                    noarch                                                    3.1.13-1.amzn2023.0.3                                                        amazonlinux                                                    9.2 k
 mariadb105-common                                                             x86_64                                                    3:10.5.25-1.amzn2023.0.1                                                     amazonlinux                                                     29 k
 perl-Sys-Hostname                                                             x86_64                                                    1.23-477.amzn2023.0.6                                                        amazonlinux                                                     18 k

Transaction Summary
===========================================================================================================================================================================================================================================================================================
Install  5 Packages

Total download size: 1.8 M
Installed size: 19 M
Downloading Packages:
(1/5): mariadb-connector-c-config-3.1.13-1.amzn2023.0.3.noarch.rpm                                                                                                                                                                                          94 kB/s | 9.2 kB     00:00    
(2/5): mariadb105-common-10.5.25-1.amzn2023.0.1.x86_64.rpm                                                                                                                                                                                                 1.2 MB/s |  29 kB     00:00    
(3/5): mariadb-connector-c-3.1.13-1.amzn2023.0.3.x86_64.rpm                                                                                                                                                                                                1.5 MB/s | 196 kB     00:00    
(4/5): perl-Sys-Hostname-1.23-477.amzn2023.0.6.x86_64.rpm                                                                                                                                                                                                  777 kB/s |  18 kB     00:00    
(5/5): mariadb105-10.5.25-1.amzn2023.0.1.x86_64.rpm                                                                                                                                                                                                        9.2 MB/s | 1.6 MB     00:00    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                                      6.9 MB/s | 1.8 MB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                                                                                                                   1/1 
  Installing       : mariadb-connector-c-config-3.1.13-1.amzn2023.0.3.noarch                                                                                                                                                                                                           1/5 
  Installing       : mariadb-connector-c-3.1.13-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                  2/5 
  Installing       : mariadb105-common-3:10.5.25-1.amzn2023.0.1.x86_64                                                                                                                                                                                                                 3/5 
  Installing       : perl-Sys-Hostname-1.23-477.amzn2023.0.6.x86_64                                                                                                                                                                                                                    4/5 
  Installing       : mariadb105-3:10.5.25-1.amzn2023.0.1.x86_64                                                                                                                                                                                                                        5/5 
  Running scriptlet: mariadb105-3:10.5.25-1.amzn2023.0.1.x86_64                                                                                                                                                                                                                        5/5 
  Verifying        : mariadb-connector-c-3.1.13-1.amzn2023.0.3.x86_64                                                                                                                                                                                                                  1/5 
  Verifying        : mariadb-connector-c-config-3.1.13-1.amzn2023.0.3.noarch                                                                                                                                                                                                           2/5 
  Verifying        : mariadb105-3:10.5.25-1.amzn2023.0.1.x86_64                                                                                                                                                                                                                        3/5 
  Verifying        : mariadb105-common-3:10.5.25-1.amzn2023.0.1.x86_64                                                                                                                                                                                                                 4/5 
  Verifying        : perl-Sys-Hostname-1.23-477.amzn2023.0.6.x86_64                                                                                                                                                                                                                    5/5 

Installed:
  mariadb-connector-c-3.1.13-1.amzn2023.0.3.x86_64        mariadb-connector-c-config-3.1.13-1.amzn2023.0.3.noarch        mariadb105-3:10.5.25-1.amzn2023.0.1.x86_64        mariadb105-common-3:10.5.25-1.amzn2023.0.1.x86_64        perl-Sys-Hostname-1.23-477.amzn2023.0.6.x86_64       

Complete!
sh-5.2$ git clone https://github.com/aws-samples/amazon-elasticache-samples/
Cloning into 'amazon-elasticache-samples'...
remote: Enumerating objects: 766, done.
remote: Counting objects: 100% (126/126), done.
remote: Compressing objects: 100% (86/86), done.
remote: Total 766 (delta 93), reused 46 (delta 39), pack-reused 640 (from 1)
Receiving objects: 100% (766/766), 27.45 MiB | 15.83 MiB/s, done.
Resolving deltas: 100% (364/364), done.
sh-5.2$ cd amazon-elasticache-samples/database-caching
sh-5.2$ python3 -m venv venv
sh-5.2$ source ./venv/bin/activate
(venv) sh-5.2$ pip3 install -r requirements.txt
Collecting PyMySQL==1.1.1
  Downloading PyMySQL-1.1.1-py3-none-any.whl (44 kB)
     |████████████████████████████████| 44 kB 2.8 MB/s             
Collecting redis==3.2.1
  Downloading redis-3.2.1-py2.py3-none-any.whl (65 kB)
     |████████████████████████████████| 65 kB 5.4 MB/s             
Installing collected packages: redis, PyMySQL
Successfully installed PyMySQL-1.1.1 redis-3.2.1
WARNING: You are using pip version 21.3.1; however, version 24.2 is available.
You should consider upgrading via the '/home/ssm-user/amazon-elasticache-samples/database-caching/venv/bin/python3 -m pip install --upgrade pip' command.
```
:::note warn
**<INS>公式ハンズオン上の手順</INS>**
sudo yum install git -y
sudo yum install mysql -y
sudo yum install python3 -y
pip3 install --user virtualenv
git clone https://github.com/aws-samples/amazon-elasticache-samples/
cd amazon-elasticache-samples/database-caching
virtualenv venv
source ./venv/bin/activate
pip3 install -r requirements.txt

<font color="Red">※EC2をamazon linux 2023に変更しているため手順変更</font>
:::
# Module 1: Create a Redis Cluster
## セキュリティグループ作成 (タブ1)
### 変数
```bash:コマンド
# セキュリティグループ名
ELC_SG_NAME='elc-tutorial-sg' \
&& echo ${ELC_SG_NAME}

# セキュリティグループ説明
ELC_SG_DESC='elc-tutorial-sg' \
&& echo ${ELC_SG_DESC}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ名
[cloudshell-user@ip-10-132-66-29 ~]$ ELC_SG_NAME='elc-tutorial-sg' \
> && echo ${ELC_SG_NAME}
elc-tutorial-sg
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ説明
[cloudshell-user@ip-10-132-66-29 ~]$ ELC_SG_DESC='elc-tutorial-sg' \
> && echo ${ELC_SG_DESC}
elc-tutorial-sg
```
### 作成
```bash:コマンド
# セキュリティグループ作成
aws ec2 create-security-group \
    --group-name ${ELC_SG_NAME} \
    --description "${ELC_SG_DESC}" \
    --vpc-id ${VPC_ID}

# ID取得
ELC_SG_ID=$( \
    aws ec2 describe-security-groups \
        --filters Name=vpc-id,Values=${VPC_ID} \
                  Name=group-name,Values=${ELC_SG_NAME} \
        --query "SecurityGroups[].GroupId" \
        --output text
) \
&& echo ${ELC_SG_ID}

# ルール追加
aws ec2 authorize-security-group-ingress \
    --group-id ${ELC_SG_ID} \
    --protocol tcp \
    --port 6379 \
    --cidr ${CIDR_BLOCK_0}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-security-group \
>     --group-name ${ELC_SG_NAME} \
>     --description "${ELC_SG_DESC}" \
>     --vpc-id ${VPC_ID}
{
    "GroupId": "sg-0c9b06ce3e6f8c26f"
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ID取得
[cloudshell-user@ip-10-132-66-29 ~]$ ELC_SG_ID=$( \
>     aws ec2 describe-security-groups \
>         --filters Name=vpc-id,Values=${VPC_ID} \
>                   Name=group-name,Values=${ELC_SG_NAME} \
>         --query "SecurityGroups[].GroupId" \
>         --output text
> ) \
> && echo ${ELC_SG_ID}
sg-0c9b06ce3e6f8c26f
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ルール追加
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 authorize-security-group-ingress \
>     --group-id ${ELC_SG_ID} \
>     --protocol tcp \
>     --port 6379 \
>     --cidr ${CIDR_BLOCK_0}
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-0902bbcea0920d754",
            "GroupId": "sg-0c9b06ce3e6f8c26f",
            "GroupOwnerId": "999999999999",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 6379,
            "ToPort": 6379,
            "CidrIpv4": "10.0.0.0/24"
        }
    ]
}
```
## キャッシュサブネットグループ作成 (タブ1)
### 変数
```bash:コマンド
CACHESUBNETGROUPNAME="elc-tutorial-subnet" \
&& echo ${CACHESUBNETGROUPNAME}

CACHESUBNETGROUPDESCRIPTION="Tutorial Subnet Group" \
&& echo ${CACHESUBNETGROUPDESCRIPTION}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ CACHESUBNETGROUPNAME="elc-tutorial-subnet" \
> && echo ${CACHESUBNETGROUPNAME}
elc-tutorial-subnet
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ CACHESUBNETGROUPDESCRIPTION="Tutorial Subnet Group" \
> && echo ${CACHESUBNETGROUPDESCRIPTION}
Tutorial Subnet Group
```
### 作成
```bash:コマンド
aws elasticache create-cache-subnet-group \
    --cache-subnet-group-name ${CACHESUBNETGROUPNAME} \
    --cache-subnet-group-description "${CACHESUBNETGROUPDESCRIPTION}" \
    --subnet-ids ${SUBNET_ID_1} ${SUBNET_ID_2} ${SUBNET_ID_3}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache create-cache-subnet-group \
>     --cache-subnet-group-name ${CACHESUBNETGROUPNAME} \
>     --cache-subnet-group-description "${CACHESUBNETGROUPDESCRIPTION}" \
>     --subnet-ids ${SUBNET_ID_1} ${SUBNET_ID_2} ${SUBNET_ID_3}
{
    "CacheSubnetGroup": {
        "CacheSubnetGroupName": "elc-tutorial-subnet",
        "CacheSubnetGroupDescription": "Tutorial Subnet Group",
        "VpcId": "vpc-02f245097860e1f1c",
        "Subnets": [
            {
                "SubnetIdentifier": "subnet-08c662c844ea24a8c",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1d"
                },
                "SupportedNetworkTypes": [
                    "ipv4"
                ]
            },
            {
                "SubnetIdentifier": "subnet-0963cc13256b4e3f6",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1a"
                },
                "SupportedNetworkTypes": [
                    "ipv4"
                ]
            },
            {
                "SubnetIdentifier": "subnet-0834139fed8def7d4",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1c"
                },
                "SupportedNetworkTypes": [
                    "ipv4"
                ]
            }
        ],
        "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:subnetgroup:elc-tutorial-subnet",
        "SupportedNetworkTypes": [
            "ipv4"
        ]
    }
}
```
## Redis クラスター作成 (タブ1)
### 変数
```bash:コマンド
# キャッシュの名前
REPLICATION_GROUP_ID="elc-tutorial" \
&& echo ${REPLICATION_GROUP_ID}

# キャッシュの説明
REPLICATION_GROUP_DESC="Tutorial example" \
&& echo ${REPLICATION_GROUP_DESC}

# レプリケーション数
REPLICAS_PER_NODE_GROUP=1 \
&& echo ${REPLICAS_PER_NODE_GROUP}

# クラスターノードタイプ
CACHE_NODE_TYPE="cache.t3.micro" \
&& echo ${CACHE_NODE_TYPE}

# クラスターパラメータグループ
CACHE_PARAMETER_GROUP="default.redis7" \
&& echo ${CACHE_PARAMETER_GROUP}

# クラスターエンジンバージョン
ENGINE_VERSION="7.1" \
&& echo ${ENGINE_VERSION}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # キャッシュの名前
[cloudshell-user@ip-10-132-66-29 ~]$ REPLICATION_GROUP_ID="elc-tutorial" \
> && echo ${REPLICATION_GROUP_ID}
elc-tutorial
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # キャッシュの説明
[cloudshell-user@ip-10-132-66-29 ~]$ REPLICATION_GROUP_DESC="Tutorial example" \
> && echo ${REPLICATION_GROUP_DESC}
Tutorial example
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # レプリケーション数
[cloudshell-user@ip-10-132-66-29 ~]$ REPLICAS_PER_NODE_GROUP=1 \
> && echo ${REPLICAS_PER_NODE_GROUP}
1
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # クラスターノードタイプ
[cloudshell-user@ip-10-132-66-29 ~]$ CACHE_NODE_TYPE="cache.t3.micro" \
> && echo ${CACHE_NODE_TYPE}
cache.t3.micro
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # クラスターパラメータグループ
[cloudshell-user@ip-10-132-66-29 ~]$ CACHE_PARAMETER_GROUP="default.redis7" \
> && echo ${CACHE_PARAMETER_GROUP}
default.redis7
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # クラスターエンジンバージョン
[cloudshell-user@ip-10-132-66-29 ~]$ ENGINE_VERSION="7.1" \
> && echo ${ENGINE_VERSION}
7.1
```
### 作成
```bash:コマンド
# Redis クラスター作成
aws elasticache create-replication-group \
    --replication-group-id ${REPLICATION_GROUP_ID} \
    --replication-group-description "${REPLICATION_GROUP_DESC}" \
    --replicas-per-node-group ${REPLICAS_PER_NODE_GROUP} \
    --cache-node-type ${CACHE_NODE_TYPE} \
    --cache-parameter-group ${CACHE_PARAMETER_GROUP} \
    --engine redis \
    --engine-version ${ENGINE_VERSION} \
    --cache-subnet-group-name ${CACHESUBNETGROUPNAME} \
    --security-group-ids ${ELC_SG_ID} \
    --automatic-failover-enabled \
    --multi-az-enabled \
    --cluster-mode disabled \
    --snapshot-retention-limit 0 \
    --no-auto-minor-version-upgrade

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # Redis クラスター作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache create-replication-group \
>     --replication-group-id ${REPLICATION_GROUP_ID} \
>     --replication-group-description "${REPLICATION_GROUP_DESC}" \
>     --replicas-per-node-group ${REPLICAS_PER_NODE_GROUP} \
>     --cache-node-type ${CACHE_NODE_TYPE} \
>     --cache-parameter-group ${CACHE_PARAMETER_GROUP} \
>     --engine redis \
>     --engine-version ${ENGINE_VERSION} \
>     --cache-subnet-group-name ${CACHESUBNETGROUPNAME} \
>     --security-group-ids ${ELC_SG_ID} \
>     --automatic-failover-enabled \
>     --multi-az-enabled \
>     --cluster-mode disabled \
>     --snapshot-retention-limit 0 \
>     --no-auto-minor-version-upgrade
{
    "ReplicationGroup": {
        "ReplicationGroupId": "elc-tutorial",
        "Description": "Tutorial example",
        "GlobalReplicationGroupInfo": {},
        "Status": "creating",
        "PendingModifiedValues": {},
        "MemberClusters": [
            "elc-tutorial-001",
            "elc-tutorial-002"
        ],
        "AutomaticFailover": "enabling",
        "MultiAZ": "enabled",
        "SnapshotRetentionLimit": 0,
        "SnapshotWindow": "13:00-14:00",
        "ClusterEnabled": false,
        "CacheNodeType": "cache.t3.micro",
        "TransitEncryptionEnabled": false,
        "AtRestEncryptionEnabled": false,
        "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:replicationgroup:elc-tutorial",
        "LogDeliveryConfigurations": [],
        "ReplicationGroupCreateTime": "2024-08-18T05:35:43.692000+00:00",
        "DataTiering": "disabled",
        "AutoMinorVersionUpgrade": false,
        "NetworkType": "ipv4",
        "IpDiscovery": "ipv4",
        "ClusterMode": "disabled"
    }
}
```
:::note warn
Redis クラスター作成完了までおよそ15分かかる
以後の作業は作成完了後に実施
:::
### 確認
```bash:コマンド
# レプリケーショングループの詳細
aws elasticache describe-replication-groups \
    --replication-group-id ${REPLICATION_GROUP_ID} \
    --no-cli-pager

# クラスターの詳細
aws elasticache describe-cache-clusters \
    --no-cli-pager

# リザーブドノードの詳細
aws elasticache describe-reserved-cache-nodes \
    --no-cli-pager

# プライマリエンドポイントの確認
aws elasticache describe-replication-groups \
    --replication-group-id ${REPLICATION_GROUP_ID} \
    --query ReplicationGroups[].NodeGroups[].PrimaryEndpoint.Address \
    --output text

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # レプリケーショングループの詳細
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache describe-replication-groups \
>     --replication-group-id ${REPLICATION_GROUP_ID} \
>     --no-cli-pager
{
    "ReplicationGroups": [
        {
            "ReplicationGroupId": "elc-tutorial",
            "Description": "Tutorial example",
            "GlobalReplicationGroupInfo": {},
            "Status": "available",
            "PendingModifiedValues": {},
            "MemberClusters": [
                "elc-tutorial-001",
                "elc-tutorial-002"
            ],
            "NodeGroups": [
                {
                    "NodeGroupId": "0001",
                    "Status": "available",
                    "PrimaryEndpoint": {
                        "Address": "elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com",
                        "Port": 6379
                    },
                    "ReaderEndpoint": {
                        "Address": "elc-tutorial-ro.veuk10.ng.0001.apne1.cache.amazonaws.com",
                        "Port": 6379
                    },
                    "NodeGroupMembers": [
                        {
                            "CacheClusterId": "elc-tutorial-001",
                            "CacheNodeId": "0001",
                            "ReadEndpoint": {
                                "Address": "elc-tutorial-001.veuk10.0001.apne1.cache.amazonaws.com",
                                "Port": 6379
                            },
                            "PreferredAvailabilityZone": "ap-northeast-1c",
                            "CurrentRole": "primary"
                        },
                        {
                            "CacheClusterId": "elc-tutorial-002",
                            "CacheNodeId": "0001",
                            "ReadEndpoint": {
                                "Address": "elc-tutorial-002.veuk10.0001.apne1.cache.amazonaws.com",
                                "Port": 6379
                            },
                            "PreferredAvailabilityZone": "ap-northeast-1a",
                            "CurrentRole": "replica"
                        }
                    ]
                }
            ],
            "AutomaticFailover": "enabled",
            "MultiAZ": "enabled",
            "SnapshotRetentionLimit": 0,
            "SnapshotWindow": "13:00-14:00",
            "ClusterEnabled": false,
            "CacheNodeType": "cache.t3.micro",
            "AuthTokenEnabled": false,
            "TransitEncryptionEnabled": false,
            "AtRestEncryptionEnabled": false,
            "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:replicationgroup:elc-tutorial",
            "LogDeliveryConfigurations": [],
            "ReplicationGroupCreateTime": "2024-08-18T05:35:43.692000+00:00",
            "DataTiering": "disabled",
            "AutoMinorVersionUpgrade": false,
            "NetworkType": "ipv4",
            "IpDiscovery": "ipv4",
            "ClusterMode": "disabled"
        }
    ]
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # クラスターの詳細
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache describe-cache-clusters \
>     --no-cli-pager
{
    "CacheClusters": [
        {
            "CacheClusterId": "elc-tutorial-001",
            "ClientDownloadLandingPage": "https://console.aws.amazon.com/elasticache/home#client-download:",
            "CacheNodeType": "cache.t3.micro",
            "Engine": "redis",
            "EngineVersion": "7.1.0",
            "CacheClusterStatus": "available",
            "NumCacheNodes": 1,
            "PreferredAvailabilityZone": "ap-northeast-1c",
            "CacheClusterCreateTime": "2024-08-18T05:48:07.909000+00:00",
            "PreferredMaintenanceWindow": "mon:17:00-mon:18:00",
            "PendingModifiedValues": {},
            "CacheSecurityGroups": [],
            "CacheParameterGroup": {
                "CacheParameterGroupName": "default.redis7",
                "ParameterApplyStatus": "in-sync",
                "CacheNodeIdsToReboot": []
            },
            "CacheSubnetGroupName": "elc-tutorial-subnet",
            "AutoMinorVersionUpgrade": false,
            "SecurityGroups": [
                {
                    "SecurityGroupId": "sg-0c9b06ce3e6f8c26f",
                    "Status": "active"
                }
            ],
            "ReplicationGroupId": "elc-tutorial",
            "SnapshotRetentionLimit": 0,
            "SnapshotWindow": "13:00-14:00",
            "AuthTokenEnabled": false,
            "TransitEncryptionEnabled": false,
            "AtRestEncryptionEnabled": false,
            "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:cluster:elc-tutorial-001",
            "ReplicationGroupLogDeliveryEnabled": false,
            "LogDeliveryConfigurations": [],
            "NetworkType": "ipv4",
            "IpDiscovery": "ipv4"
        },
        {
            "CacheClusterId": "elc-tutorial-002",
            "ClientDownloadLandingPage": "https://console.aws.amazon.com/elasticache/home#client-download:",
            "CacheNodeType": "cache.t3.micro",
            "Engine": "redis",
            "EngineVersion": "7.1.0",
            "CacheClusterStatus": "available",
            "NumCacheNodes": 1,
            "PreferredAvailabilityZone": "ap-northeast-1a",
            "CacheClusterCreateTime": "2024-08-18T05:48:07.909000+00:00",
            "PreferredMaintenanceWindow": "mon:17:00-mon:18:00",
            "PendingModifiedValues": {},
            "CacheSecurityGroups": [],
            "CacheParameterGroup": {
                "CacheParameterGroupName": "default.redis7",
                "ParameterApplyStatus": "in-sync",
                "CacheNodeIdsToReboot": []
            },
            "CacheSubnetGroupName": "elc-tutorial-subnet",
            "AutoMinorVersionUpgrade": false,
            "SecurityGroups": [
                {
                    "SecurityGroupId": "sg-0c9b06ce3e6f8c26f",
                    "Status": "active"
                }
            ],
            "ReplicationGroupId": "elc-tutorial",
            "SnapshotRetentionLimit": 0,
            "SnapshotWindow": "13:00-14:00",
            "AuthTokenEnabled": false,
            "TransitEncryptionEnabled": false,
            "AtRestEncryptionEnabled": false,
            "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:cluster:elc-tutorial-002",
            "ReplicationGroupLogDeliveryEnabled": false,
            "LogDeliveryConfigurations": [],
            "NetworkType": "ipv4",
            "IpDiscovery": "ipv4"
        }
    ]
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # リザーブドノードの詳細
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache describe-reserved-cache-nodes \
>     --no-cli-pager
{
    "ReservedCacheNodes": []
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # プライマリエンドポイントの確認
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache describe-replication-groups \
>     --replication-group-id ${REPLICATION_GROUP_ID} \
>     --query ReplicationGroups[].NodeGroups[].PrimaryEndpoint.Address \
>     --output text
elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com
```
# Module 2: Create a MySQL database
## セキュリティグループ作成 (タブ1)
### 変数
```bash:コマンド
# セキュリティグループ名
RDS_SG_NAME='handson-rds-sg' \
&& echo ${RDS_SG_NAME}

# セキュリティグループ説明
RDS_SG_DESC='handson-rds-sg' \
&& echo ${RDS_SG_DESC}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ名
[cloudshell-user@ip-10-132-66-29 ~]$ RDS_SG_NAME='handson-rds-sg' \
> && echo ${RDS_SG_NAME}
handson-rds-sg
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ説明
[cloudshell-user@ip-10-132-66-29 ~]$ RDS_SG_DESC='handson-rds-sg' \
> && echo ${RDS_SG_DESC}
handson-rds-sg
```
### 作成
```bash:コマンド
# セキュリティグループ作成
aws ec2 create-security-group \
    --group-name ${RDS_SG_NAME} \
    --description "${RDS_SG_DESC}" \
    --vpc-id ${VPC_ID}

# ID取得
RDS_SG_ID=$( \
    aws ec2 describe-security-groups \
        --filters Name=vpc-id,Values=${VPC_ID} \
                  Name=group-name,Values=${RDS_SG_NAME} \
        --query "SecurityGroups[].GroupId" \
        --output text
) \
&& echo ${RDS_SG_ID}

# ルール追加
aws ec2 authorize-security-group-ingress \
    --group-id ${RDS_SG_ID} \
    --protocol tcp \
    --port 3306 \
    --cidr ${CIDR_BLOCK_0}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ作成
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 create-security-group \
>     --group-name ${RDS_SG_NAME} \
>     --description "${RDS_SG_DESC}" \
>     --vpc-id ${VPC_ID}
{
    "GroupId": "sg-02f060176da122148"
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ID取得
[cloudshell-user@ip-10-132-66-29 ~]$ RDS_SG_ID=$( \
>     aws ec2 describe-security-groups \
>         --filters Name=vpc-id,Values=${VPC_ID} \
>                   Name=group-name,Values=${RDS_SG_NAME} \
>         --query "SecurityGroups[].GroupId" \
>         --output text
> ) \
> && echo ${RDS_SG_ID}
sg-02f060176da122148
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ルール追加
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 authorize-security-group-ingress \
>     --group-id ${RDS_SG_ID} \
>     --protocol tcp \
>     --port 3306 \
>     --cidr ${CIDR_BLOCK_0}
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-0fea6b68312fb3b3e",
            "GroupId": "sg-02f060176da122148",
            "GroupOwnerId": "999999999999",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 3306,
            "ToPort": 3306,
            "CidrIpv4": "10.0.0.0/24"
        }
    ]
}
```
## サブネットグループ作成 (タブ1)
### 変数
```bash:コマンド
DB_SUBNET_GROUP_NAME='rds-subnet-group' \
&& echo ${DB_SUBNET_GROUP_NAME}

DB_SUBNET_GROUP_DESC='rds-subnet-group' \
&& echo ${DB_SUBNET_GROUP_DESC}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ DB_SUBNET_GROUP_NAME='rds-subnet-group' \
> && echo ${DB_SUBNET_GROUP_NAME}
rds-subnet-group
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ DB_SUBNET_GROUP_DESC='rds-subnet-group' \
> && echo ${DB_SUBNET_GROUP_DESC}
rds-subnet-group
```
### 作成
```bash:コマンド
aws rds create-db-subnet-group \
    --db-subnet-group-name ${DB_SUBNET_GROUP_NAME} \
    --db-subnet-group-description ${DB_SUBNET_GROUP_DESC} \
    --subnet-ids ${SUBNET_ID_1} ${SUBNET_ID_2} ${SUBNET_ID_3}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds create-db-subnet-group \
>     --db-subnet-group-name ${DB_SUBNET_GROUP_NAME} \
>     --db-subnet-group-description ${DB_SUBNET_GROUP_DESC} \
>     --subnet-ids ${SUBNET_ID_1} ${SUBNET_ID_2} ${SUBNET_ID_3}
{
    "DBSubnetGroup": {
        "DBSubnetGroupName": "rds-subnet-group",
        "DBSubnetGroupDescription": "rds-subnet-group",
        "VpcId": "vpc-02f245097860e1f1c",
        "SubnetGroupStatus": "Complete",
        "Subnets": [
            {
                "SubnetIdentifier": "subnet-08c662c844ea24a8c",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1d"
                },
                "SubnetOutpost": {},
                "SubnetStatus": "Active"
            },
            {
                "SubnetIdentifier": "subnet-0963cc13256b4e3f6",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1a"
                },
                "SubnetOutpost": {},
                "SubnetStatus": "Active"
            },
            {
                "SubnetIdentifier": "subnet-0834139fed8def7d4",
                "SubnetAvailabilityZone": {
                    "Name": "ap-northeast-1c"
                },
                "SubnetOutpost": {},
                "SubnetStatus": "Active"
            }
        ],
        "DBSubnetGroupArn": "arn:aws:rds:ap-northeast-1:999999999999:subgrp:rds-subnet-group",
        "SupportedNetworkTypes": [
            "IPV4"
        ]
    }
}
```
## RDS作成 (タブ1)
### 変数
```bash:コマンド
# DB インスタンス識別子
DB_INSTANCE_IDENTIFIER="database-1" \
&& echo ${DB_INSTANCE_IDENTIFIER}

# インスタンスクラス
DB_INSTANCE_CLASS="db.t3.micro" \
&& echo ${DB_INSTANCE_CLASS}

# エンジンのタイプ
ENGINE="mysql" \
&& echo ${ENGINE}

# マスターユーザー名
MASTER_USERNAME="admin" \
&& echo ${MASTER_USERNAME}

# マスターパスワード
MASTER_USER_PASSWORD=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c12) \
&& echo ${MASTER_USER_PASSWORD}

# ストレージタイプ
STORAGE_TYPE='gp2' \
&& echo ${STORAGE_TYPE}

# ストレージ割り当て
ALLOCATED_STORAGE=20 \
&& echo ${ALLOCATED_STORAGE}

# 最大ストレージしきい値
MAX_ALLOCATED_STORAGE=1000 \
&& echo ${MAX_ALLOCATED_STORAGE}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # DB インスタンス識別子
[cloudshell-user@ip-10-132-66-29 ~]$ DB_INSTANCE_IDENTIFIER="database-1" \
> && echo ${DB_INSTANCE_IDENTIFIER}
database-1
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスクラス
[cloudshell-user@ip-10-132-66-29 ~]$ DB_INSTANCE_CLASS="db.t3.micro" \
> && echo ${DB_INSTANCE_CLASS}
db.t3.micro
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # エンジンのタイプ
[cloudshell-user@ip-10-132-66-29 ~]$ ENGINE="mysql" \
> && echo ${ENGINE}
mysql
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # マスターユーザー名
[cloudshell-user@ip-10-132-66-29 ~]$ MASTER_USERNAME="admin" \
> && echo ${MASTER_USERNAME}
admin
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # マスターパスワード
[cloudshell-user@ip-10-132-66-29 ~]$ MASTER_USER_PASSWORD=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c12) \
> && echo ${MASTER_USER_PASSWORD}
QwOdAGb3WkR1
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ストレージタイプ
[cloudshell-user@ip-10-132-66-29 ~]$ STORAGE_TYPE='gp2' \
> && echo ${STORAGE_TYPE}
gp2
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ストレージ割り当て
[cloudshell-user@ip-10-132-66-29 ~]$ ALLOCATED_STORAGE=20 \
> && echo ${ALLOCATED_STORAGE}
20
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # 最大ストレージしきい値
[cloudshell-user@ip-10-132-66-29 ~]$ MAX_ALLOCATED_STORAGE=1000 \
> && echo ${MAX_ALLOCATED_STORAGE}
1000
```
### 作成
```bash:コマンド
aws rds create-db-instance \
  --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
  --allocated-storage ${ALLOCATED_STORAGE} \
  --db-instance-class ${DB_INSTANCE_CLASS} \
  --engine ${ENGINE} \
  --master-username ${MASTER_USERNAME} \
  --master-user-password ${MASTER_USER_PASSWORD} \
  --vpc-security-group-ids ${RDS_SG_ID} \
  --availability-zone ${AZ_1} \
  --db-subnet-group-name ${DB_SUBNET_GROUP_NAME} \
  --backup-retention-period 0 \
  --no-multi-az \
  --no-auto-minor-version-upgrade \
  --storage-type ${STORAGE_TYPE} \
  --no-publicly-accessible \
  --no-storage-encrypted \
  --no-enable-performance-insights \
  --max-allocated-storage ${MAX_ALLOCATED_STORAGE} \
  --no-cli-pager
  
```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds create-db-instance \
>   --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
>   --allocated-storage ${ALLOCATED_STORAGE} \
>   --db-instance-class ${DB_INSTANCE_CLASS} \
>   --engine ${ENGINE} \
>   --master-username ${MASTER_USERNAME} \
>   --master-user-password ${MASTER_USER_PASSWORD} \
>   --vpc-security-group-ids ${RDS_SG_ID} \
>   --availability-zone ${AZ_1} \
>   --db-subnet-group-name ${DB_SUBNET_GROUP_NAME} \
>   --backup-retention-period 0 \
>   --no-multi-az \
>   --no-auto-minor-version-upgrade \
>   --storage-type ${STORAGE_TYPE} \
>   --no-publicly-accessible \
>   --no-storage-encrypted \
>   --no-enable-performance-insights \
>   --max-allocated-storage ${MAX_ALLOCATED_STORAGE} \
>   --no-cli-pager
{
    "DBInstance": {
        "DBInstanceIdentifier": "database-1",
        "DBInstanceClass": "db.t3.micro",
        "Engine": "mysql",
        "DBInstanceStatus": "creating",
        "MasterUsername": "admin",
        "AllocatedStorage": 20,
        "PreferredBackupWindow": "17:24-17:54",
        "BackupRetentionPeriod": 0,
        "DBSecurityGroups": [],
        "VpcSecurityGroups": [
            {
                "VpcSecurityGroupId": "sg-02f060176da122148",
                "Status": "active"
            }
        ],
        "DBParameterGroups": [
            {
                "DBParameterGroupName": "default.mysql8.0",
                "ParameterApplyStatus": "in-sync"
            }
        ],
        "AvailabilityZone": "ap-northeast-1a",
        "DBSubnetGroup": {
            "DBSubnetGroupName": "rds-subnet-group",
            "DBSubnetGroupDescription": "rds-subnet-group",
            "VpcId": "vpc-02f245097860e1f1c",
            "SubnetGroupStatus": "Complete",
            "Subnets": [
                {
                    "SubnetIdentifier": "subnet-08c662c844ea24a8c",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1d"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                },
                {
                    "SubnetIdentifier": "subnet-0963cc13256b4e3f6",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1a"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                },
                {
                    "SubnetIdentifier": "subnet-0834139fed8def7d4",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1c"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                }
            ]
        },
        "PreferredMaintenanceWindow": "wed:15:37-wed:16:07",
        "PendingModifiedValues": {
            "MasterUserPassword": "****"
        },
        "MultiAZ": false,
        "EngineVersion": "8.0.35",
        "AutoMinorVersionUpgrade": false,
        "ReadReplicaDBInstanceIdentifiers": [],
        "LicenseModel": "general-public-license",
        "OptionGroupMemberships": [
            {
                "OptionGroupName": "default:mysql-8-0",
                "Status": "in-sync"
            }
        ],
        "PubliclyAccessible": false,
        "StorageType": "gp2",
        "DbInstancePort": 0,
        "StorageEncrypted": false,
        "DbiResourceId": "db-QOTUXN2TRESVCMVOXEIMBJTTPI",
        "CACertificateIdentifier": "rds-ca-rsa2048-g1",
        "DomainMemberships": [],
        "CopyTagsToSnapshot": false,
        "MonitoringInterval": 0,
        "DBInstanceArn": "arn:aws:rds:ap-northeast-1:999999999999:db:database-1",
        "IAMDatabaseAuthenticationEnabled": false,
        "PerformanceInsightsEnabled": false,
        "DeletionProtection": false,
        "AssociatedRoles": [],
        "MaxAllocatedStorage": 1000,
        "TagList": [],
        "CustomerOwnedIpEnabled": false,
        "BackupTarget": "region",
        "NetworkType": "IPV4",
        "StorageThroughput": 0,
        "CertificateDetails": {
            "CAIdentifier": "rds-ca-rsa2048-g1"
        },
        "DedicatedLogVolume": false,
        "EngineLifecycleSupport": "open-source-rds-extended-support"
    }
}
```
:::note warn
RDS 作成完了までおよそ5分かかる
以後の作業は作成完了後に実施
:::
### 確認
```bash:コマンド
# 詳細確認
aws rds describe-db-instances \
    --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
    --no-cli-pager

# エンドポイントアドレス確認
aws rds describe-db-instances \
    --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
    --query DBInstances[].Endpoint.Address \
    --output text

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # 詳細確認
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds describe-db-instances \
>     --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
>     --no-cli-pager
{
    "DBInstances": [
        {
            "DBInstanceIdentifier": "database-1",
            "DBInstanceClass": "db.t3.micro",
            "Engine": "mysql",
            "DBInstanceStatus": "available",
            "MasterUsername": "admin",
            "Endpoint": {
                "Address": "database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com",
                "Port": 3306,
                "HostedZoneId": "Z24O6O9L7SGTNB"
            },
            "AllocatedStorage": 20,
            "InstanceCreateTime": "2024-08-18T06:04:41.150000+00:00",
            "PreferredBackupWindow": "17:24-17:54",
            "BackupRetentionPeriod": 0,
            "DBSecurityGroups": [],
            "VpcSecurityGroups": [
                {
                    "VpcSecurityGroupId": "sg-02f060176da122148",
                    "Status": "active"
                }
            ],
            "DBParameterGroups": [
                {
                    "DBParameterGroupName": "default.mysql8.0",
                    "ParameterApplyStatus": "in-sync"
                }
            ],
            "AvailabilityZone": "ap-northeast-1a",
            "DBSubnetGroup": {
                "DBSubnetGroupName": "rds-subnet-group",
                "DBSubnetGroupDescription": "rds-subnet-group",
                "VpcId": "vpc-02f245097860e1f1c",
                "SubnetGroupStatus": "Complete",
                "Subnets": [
                    {
                        "SubnetIdentifier": "subnet-08c662c844ea24a8c",
                        "SubnetAvailabilityZone": {
                            "Name": "ap-northeast-1d"
                        },
                        "SubnetOutpost": {},
                        "SubnetStatus": "Active"
                    },
                    {
                        "SubnetIdentifier": "subnet-0963cc13256b4e3f6",
                        "SubnetAvailabilityZone": {
                            "Name": "ap-northeast-1a"
                        },
                        "SubnetOutpost": {},
                        "SubnetStatus": "Active"
                    },
                    {
                        "SubnetIdentifier": "subnet-0834139fed8def7d4",
                        "SubnetAvailabilityZone": {
                            "Name": "ap-northeast-1c"
                        },
                        "SubnetOutpost": {},
                        "SubnetStatus": "Active"
                    }
                ]
            },
            "PreferredMaintenanceWindow": "wed:15:37-wed:16:07",
            "PendingModifiedValues": {},
            "MultiAZ": false,
            "EngineVersion": "8.0.35",
            "AutoMinorVersionUpgrade": false,
            "ReadReplicaDBInstanceIdentifiers": [],
            "LicenseModel": "general-public-license",
            "OptionGroupMemberships": [
                {
                    "OptionGroupName": "default:mysql-8-0",
                    "Status": "in-sync"
                }
            ],
            "PubliclyAccessible": false,
            "StorageType": "gp2",
            "DbInstancePort": 0,
            "StorageEncrypted": false,
            "DbiResourceId": "db-QOTUXN2TRESVCMVOXEIMBJTTPI",
            "CACertificateIdentifier": "rds-ca-rsa2048-g1",
            "DomainMemberships": [],
            "CopyTagsToSnapshot": false,
            "MonitoringInterval": 0,
            "DBInstanceArn": "arn:aws:rds:ap-northeast-1:999999999999:db:database-1",
            "IAMDatabaseAuthenticationEnabled": false,
            "PerformanceInsightsEnabled": false,
            "DeletionProtection": false,
            "AssociatedRoles": [],
            "MaxAllocatedStorage": 1000,
            "TagList": [],
            "CustomerOwnedIpEnabled": false,
            "ActivityStreamStatus": "stopped",
            "BackupTarget": "region",
            "NetworkType": "IPV4",
            "StorageThroughput": 0,
            "CertificateDetails": {
                "CAIdentifier": "rds-ca-rsa2048-g1",
                "ValidTill": "2025-08-18T06:03:51+00:00"
            },
            "DedicatedLogVolume": false,
            "IsStorageConfigUpgradeAvailable": false,
            "EngineLifecycleSupport": "open-source-rds-extended-support"
        }
    ]
}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # エンドポイントアドレス確認
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds describe-db-instances \
>     --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
>     --query DBInstances[].Endpoint.Address \
>     --output text
database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com
```
# Module 3: Populate your MySQL database
## データベース作成 (タブ2)
### 変数
:::note warn
RDS_ENDPOINT_ADDRESS、MASTER_USER_PASSWORDは適宜変更
:::
```bash:コマンド
RDS_ENDPOINT_ADDRESS="database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com" \
&& echo ${RDS_ENDPOINT_ADDRESS}

MASTER_USER_PASSWORD="QwOdAGb3WkR1" \
&& echo ${MASTER_USER_PASSWORD}

```
```bash:出力
(venv) sh-5.2$ RDS_ENDPOINT_ADDRESS="database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com" \
> && echo ${RDS_ENDPOINT_ADDRESS}
database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com
(venv) sh-5.2$ 
(venv) sh-5.2$ MASTER_USER_PASSWORD="QwOdAGb3WkR1" \
> && echo ${MAS
```
### 作成
```bash:コマンド
mysql -h ${RDS_ENDPOINT_ADDRESS} -P 3306 -u admin -p${MASTER_USER_PASSWORD} < seed.sql

```
```bash:出力
(venv) sh-5.2$ mysql -h ${RDS_ENDPOINT_ADDRESS} -P 3306 -u admin -p${MASTER_USER_PASSWORD} < seed.sql
```
# Module 4: Caching and Best Practices
## Redisへの接続をテストする (タブ2)
### 変数
```bash:コマンド
export ELC_ENDPOINT_ADDRESS=elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com \
&& echo ${ELC_ENDPOINT_ADDRESS}

```
```bash:出力
(venv) sh-5.2$ export ELC_ENDPOINT_ADDRESS=elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com \
> && echo ${ELC_ENDPOINT_ADDRESS}
elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com
```
### Pythonインタプリター起動
```bash:コマンド
python

```
```bash:出力
(venv) sh-5.2$ python
Python 3.9.16 (main, Jul  5 2024, 00:00:00) 
[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```
### Redis ノードへの接続をテスト
```bash:コマンド
import os
import redis

# 環境変数の値を取得
ELC_ENDPOINT_ADDRESS = os.getenv('ELC_ENDPOINT_ADDRESS')

# Redisクライアントを初期化
client = redis.Redis.from_url(f"redis://{ELC_ENDPOINT_ADDRESS}:6379")
client.ping()
exit()

```
```bash:出力
>>> import os
>>> import redis
>>> 
>>> # 環境変数の値を取得
>>> ELC_ENDPOINT_ADDRESS = os.getenv('ELC_ENDPOINT_ADDRESS')
>>> 
>>> # Redisクライアントを初期化
>>> client = redis.Redis.from_url(f"redis://{ELC_ENDPOINT_ADDRESS}:6379")
>>> client.ping()
True
>>> exit()
(venv) sh-5.2$ 
```
## 環境を構成する (タブ2)
```bash:コマンド
export REDIS_URL=redis://${ELC_ENDPOINT_ADDRESS}:6379/
export DB_HOST=${RDS_ENDPOINT_ADDRESS}
export DB_USER=admin
export DB_PASS=${MASTER_USER_PASSWORD}
export DB_NAME=tutorial

```
```bash:出力
(venv) sh-5.2$ export REDIS_URL=redis://${ELC_ENDPOINT_ADDRESS}:6379/
(venv) sh-5.2$ export DB_HOST=${RDS_ENDPOINT_ADDRESS}
(venv) sh-5.2$ export DB_USER=admin
(venv) sh-5.2$ export DB_PASS=${MASTER_USER_PASSWORD}
(venv) sh-5.2$ export DB_NAME=tutorial
```
## SQLクエリの結果をキャッシュする (タブ2)
### スクリプト変更
:::note info
<INS>**ハンズオンのスクリプトから変更**</INS>
(変更点)
* レコードをキャッシュとデータベースのどちらから取得しているかのメッセージを表示
* モジュールごとに実行できるように変更
:::
```bash:コマンド
cat << "EOF" > example.py
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

import os
import json
import redis
import pymysql


class DB:
    def __init__(self, **params):
        params.setdefault("charset", "utf8mb4")
        params.setdefault("cursorclass", pymysql.cursors.DictCursor)

        self.mysql = pymysql.connect(**params)

    def query(self, sql):
        with self.mysql.cursor() as cursor:
            cursor.execute(sql)
            return cursor.fetchall()

    def record(self, sql, values):
        with self.mysql.cursor() as cursor:
            cursor.execute(sql, values)
            return cursor.fetchone()


# Time to live for cached data
TTL = 10

# Read the Redis credentials from the REDIS_URL environment variable.
REDIS_URL = os.environ.get('REDIS_URL')

# Read the DB credentials from the DB_* environment variables.
DB_HOST = os.environ.get('DB_HOST')
DB_USER = os.environ.get('DB_USER')
DB_PASS = os.environ.get('DB_PASS')
DB_NAME = os.environ.get('DB_NAME')

# Initialize the database
Database = DB(host=DB_HOST, user=DB_USER, password=DB_PASS, db=DB_NAME)

# Initialize the cache
Cache = redis.Redis.from_url(REDIS_URL)


def fetch(sql):
    """Retrieve records from the cache, or else from the database."""
    res = Cache.get(sql)

    if res:
        print("Retrieve records from the cache.")
        return json.loads(res)

    print("Retrieve records from the database.")
    res = Database.query(sql)
    Cache.setex(sql, TTL, json.dumps(res))
    return res


def planet(id):
    """Retrieve a record from the cache, or else from the database."""
    key = f"planet:{id}"
    res = Cache.hgetall(key)

    if res:
        print("Retrieve records from the cache.")
        return res

    print("Retrieve records from the database.")
    sql = "SELECT `id`, `name` FROM `planet` WHERE `id`=%s"
    res = Database.record(sql, (id,))

    if res:
        Cache.hmset(key, res)
        Cache.expire(key, TTL)

    return res


if __name__ == "__main__": 
    # Display the result of some queries
    print(fetch("SELECT * FROM planet"))
    print(planet(1))
    print(planet(2))
    print(planet(3))
EOF

```
```bash:出力
(venv) sh-5.2$ cat << "EOF" > example.py
> # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
> # SPDX-License-Identifier: MIT-0
> 
> import os
> import json
> import redis
> import pymysql
> 
> 
> class DB:
>     def __init__(self, **params):
>         params.setdefault("charset", "utf8mb4")
>         params.setdefault("cursorclass", pymysql.cursors.DictCursor)
> 
>         self.mysql = pymysql.connect(**params)
> 
>     def query(self, sql):
>         with self.mysql.cursor() as cursor:
>             cursor.execute(sql)
>             return cursor.fetchall()
> 
>     def record(self, sql, values):
>         with self.mysql.cursor() as cursor:
>             cursor.execute(sql, values)
>             return cursor.fetchone()
> 
> 
> # Time to live for cached data
> TTL = 10
> 
> # Read the Redis credentials from the REDIS_URL environment variable.
> REDIS_URL = os.environ.get('REDIS_URL')
> 
> # Read the DB credentials from the DB_* environment variables.
> DB_HOST = os.environ.get('DB_HOST')
> DB_USER = os.environ.get('DB_USER')
> DB_PASS = os.environ.get('DB_PASS')
> DB_NAME = os.environ.get('DB_NAME')
> 
> # Initialize the database
> Database = DB(host=DB_HOST, user=DB_USER, password=DB_PASS, db=DB_NAME)
> 
> # Initialize the cache
> Cache = redis.Redis.from_url(REDIS_URL)
> 
> 
> def fetch(sql):
>     """Retrieve records from the cache, or else from the database."""
>     res = Cache.get(sql)
> 
>     if res:
>         print("Retrieve records from the cache.")
>         return json.loads(res)
> 
>     print("Retrieve records from the database.")
>     res = Database.query(sql)
>     Cache.setex(sql, TTL, json.dumps(res))
>     return res
> 
> 
> def planet(id):
>     """Retrieve a record from the cache, or else from the database."""
>     key = f"planet:{id}"
>     res = Cache.hgetall(key)
> 
>     if res:
>         print("Retrieve records from the cache.")
>         return res
> 
>     print("Retrieve records from the database.")
>     sql = "SELECT `id`, `name` FROM `planet` WHERE `id`=%s"
>     res = Database.record(sql, (id,))
> 
>     if res:
>         Cache.hmset(key, res)
>         Cache.expire(key, TTL)
> 
>     return res
> 
> 
> if __name__ == "__main__": 
>     # Display the result of some queries
>     print(fetch("SELECT * FROM planet"))
>     print(planet(1))
>     print(planet(2))
>     print(planet(3))
> EOF
```
### スクリプト実行
```bash:コマンド
python example.py

```
```bash:出力 (キャッシュ無時)
(venv) sh-5.2$ python example.py
Retrieve records from the database.
[{'id': 1, 'name': 'Mercury'}, {'id': 2, 'name': 'Venus'}, {'id': 3, 'name': 'Earth'}, {'id': 4, 'name': 'Mars'}, {'id': 5, 'name': 'Jupiter'}, {'id': 6, 'name': 'Saturn'}, {'id': 7, 'name': 'Uranus'}, {'id': 8, 'name': 'Neptune'}]
Retrieve records from the database.
{'id': 1, 'name': 'Mercury'}
Retrieve records from the database.
{'id': 2, 'name': 'Venus'}
Retrieve records from the database.
{'id': 3, 'name': 'Earth'}
```
```bash:出力 (キャッシュ有時)
(venv) sh-5.2$ python example.py
Retrieve records from the cache.
[{'id': 1, 'name': 'Mercury'}, {'id': 2, 'name': 'Venus'}, {'id': 3, 'name': 'Earth'}, {'id': 4, 'name': 'Mars'}, {'id': 5, 'name': 'Jupiter'}, {'id': 6, 'name': 'Saturn'}, {'id': 7, 'name': 'Uranus'}, {'id': 8, 'name': 'Neptune'}]
Retrieve records from the cache.
{b'id': b'1', b'name': b'Mercury'}
Retrieve records from the cache.
{b'id': b'2', b'name': b'Venus'}
Retrieve records from the cache.
{b'id': b'3', b'name': b'Earth'}
```
### モジュールごとに実行
```bash:コマンド
# pythonインタプリター起動
python
```
```bash:出力
(venv) sh-5.2$ # pythonインタプリター起動
(venv) sh-5.2$ python
Python 3.9.16 (main, Jul  5 2024, 00:00:00) 
[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

```bash:コマンド
# モジュールのインポート
from example import fetch
from example import planet

```
```bash:出力
>>> # モジュールのインポート
>>> from example import fetch
>>> from example import planet
```

```bash:コマンド
# fetchの実行
print(fetch("SELECT * FROM planet"))

```
```bash:出力 (キャッシュ無時)
>>> # fetchの実行
>>> print(fetch("SELECT * FROM planet"))
Retrieve records from the database.
[{'id': 1, 'name': 'Mercury'}, {'id': 2, 'name': 'Venus'}, {'id': 3, 'name': 'Earth'}, {'id': 4, 'name': 'Mars'}, {'id': 5, 'name': 'Jupiter'}, {'id': 6, 'name': 'Saturn'}, {'id': 7, 'name': 'Uranus'}, {'id': 8, 'name': 'Neptune'}]
```
```bash:出力 (キャッシュ有時)
>>> # fetchの実行
>>> print(fetch("SELECT * FROM planet"))
Retrieve records from the cache.
[{'id': 1, 'name': 'Mercury'}, {'id': 2, 'name': 'Venus'}, {'id': 3, 'name': 'Earth'}, {'id': 4, 'name': 'Mars'}, {'id': 5, 'name': 'Jupiter'}, {'id': 6, 'name': 'Saturn'}, {'id': 7, 'name': 'Uranus'}, {'id': 8, 'name': 'Neptune'}]
```
```bash:コマンド
# planetの実行
print(planet(1))
print(planet(2))
print(planet(3))
print(planet(4))
print(planet(5))
print(planet(6))
print(planet(7))
print(planet(8))
print(planet(9))

```
```bash:出力 (キャッシュ無時)
>>> # planetの実行
>>> print(planet(1))
Retrieve records from the database.
{'id': 1, 'name': 'Mercury'}
>>> print(planet(2))
Retrieve records from the database.
{'id': 2, 'name': 'Venus'}
>>> print(planet(3))
Retrieve records from the database.
{'id': 3, 'name': 'Earth'}
>>> print(planet(4))
Retrieve records from the database.
{'id': 4, 'name': 'Mars'}
>>> print(planet(5))
Retrieve records from the database.
{'id': 5, 'name': 'Jupiter'}
>>> print(planet(6))
Retrieve records from the database.
{'id': 6, 'name': 'Saturn'}
>>> print(planet(7))
Retrieve records from the database.
{'id': 7, 'name': 'Uranus'}
>>> print(planet(8))
Retrieve records from the database.
{'id': 8, 'name': 'Neptune'}
>>> print(planet(9))
Retrieve records from the database.
None
```

```bash:出力 (キャッシュ有時)
>>> # planetの実行
>>> print(planet(1))
Retrieve records from the cache.
{b'id': b'1', b'name': b'Mercury'}
>>> print(planet(2))
Retrieve records from the cache.
{b'id': b'2', b'name': b'Venus'}
>>> print(planet(3))
Retrieve records from the cache.
{b'id': b'3', b'name': b'Earth'}
>>> print(planet(4))
Retrieve records from the cache.
{b'id': b'4', b'name': b'Mars'}
>>> print(planet(5))
Retrieve records from the cache.
{b'id': b'5', b'name': b'Jupiter'}
>>> print(planet(6))
Retrieve records from the cache.
{b'id': b'6', b'name': b'Saturn'}
>>> print(planet(7))
Retrieve records from the cache.
{b'id': b'7', b'name': b'Uranus'}
>>> print(planet(8))
Retrieve records from the cache.
{b'id': b'8', b'name': b'Neptune'}
>>> print(planet(9))
Retrieve records from the database.
None
```
## Session Manager切断 (タブ2)
```bash:コマンド
exit()

exit

```
```bash:出力
>>> exit()
(venv) sh-5.2$ 
(venv) sh-5.2$ exit
exit


Exiting session with sessionId: admin-pstqfi2goch6btjuk7ygzkroa4.

[cloudshell-user@ip-10-132-66-29 ~]$ 
```
# Module 5: Cleanup
## MySQLデータベースを削除する (タブ1)
```bash:コマンド
# RDS削除 (タブ1)
aws rds delete-db-instance \
    --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
    --skip-final-snapshot \
    --delete-automated-backups \
    --no-cli-pager
    
```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # RDS削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds delete-db-instance \
>     --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
>     --skip-final-snapshot \
>     --delete-automated-backups \
>     --no-cli-pager
{
    "DBInstance": {
        "DBInstanceIdentifier": "database-1",
        "DBInstanceClass": "db.t3.micro",
        "Engine": "mysql",
        "DBInstanceStatus": "deleting",
        "MasterUsername": "admin",
        "Endpoint": {
            "Address": "database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com",
            "Port": 3306,
            "HostedZoneId": "Z24O6O9L7SGTNB"
        },
        "AllocatedStorage": 20,
        "InstanceCreateTime": "2024-08-18T06:04:41.150000+00:00",
        "PreferredBackupWindow": "17:24-17:54",
        "BackupRetentionPeriod": 0,
        "DBSecurityGroups": [],
        "VpcSecurityGroups": [
            {
                "VpcSecurityGroupId": "sg-02f060176da122148",
                "Status": "active"
            }
        ],
        "DBParameterGroups": [
            {
                "DBParameterGroupName": "default.mysql8.0",
                "ParameterApplyStatus": "in-sync"
            }
        ],
        "AvailabilityZone": "ap-northeast-1a",
        "DBSubnetGroup": {
            "DBSubnetGroupName": "rds-subnet-group",
            "DBSubnetGroupDescription": "rds-subnet-group",
            "VpcId": "vpc-02f245097860e1f1c",
            "SubnetGroupStatus": "Complete",
            "Subnets": [
                {
                    "SubnetIdentifier": "subnet-08c662c844ea24a8c",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1d"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                },
                {
                    "SubnetIdentifier": "subnet-0963cc13256b4e3f6",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1a"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                },
                {
                    "SubnetIdentifier": "subnet-0834139fed8def7d4",
                    "SubnetAvailabilityZone": {
                        "Name": "ap-northeast-1c"
                    },
                    "SubnetOutpost": {},
                    "SubnetStatus": "Active"
                }
            ]
        },
        "PreferredMaintenanceWindow": "wed:15:37-wed:16:07",
        "PendingModifiedValues": {},
        "MultiAZ": false,
        "EngineVersion": "8.0.35",
        "AutoMinorVersionUpgrade": false,
        "ReadReplicaDBInstanceIdentifiers": [],
        "LicenseModel": "general-public-license",
        "OptionGroupMemberships": [
            {
                "OptionGroupName": "default:mysql-8-0",
                "Status": "in-sync"
            }
        ],
        "PubliclyAccessible": false,
        "StorageType": "gp2",
        "DbInstancePort": 0,
        "StorageEncrypted": false,
        "DbiResourceId": "db-QOTUXN2TRESVCMVOXEIMBJTTPI",
        "CACertificateIdentifier": "",
        "DomainMemberships": [],
        "CopyTagsToSnapshot": false,
        "MonitoringInterval": 0,
        "DBInstanceArn": "arn:aws:rds:ap-northeast-1:999999999999:db:database-1",
        "IAMDatabaseAuthenticationEnabled": false,
        "PerformanceInsightsEnabled": false,
        "DeletionProtection": false,
        "AssociatedRoles": [],
        "MaxAllocatedStorage": 1000,
        "TagList": [],
        "CustomerOwnedIpEnabled": false,
        "BackupTarget": "region",
        "NetworkType": "IPV4",
        "StorageThroughput": 0,
        "DedicatedLogVolume": false,
        "EngineLifecycleSupport": "open-source-rds-extended-support"
    }
}
```
:::note warn
RDS 削除完了までおよそ5分かかる
以後の作業は作成完了後に実施
:::
```bash:コマンド
# RDSサブネットグループ削除
aws rds delete-db-subnet-group \
    --db-subnet-group-name ${DB_SUBNET_GROUP_NAME}

# セキュリティグループ削除
aws ec2 delete-security-group \
    --group-id ${RDS_SG_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # RDSサブネットグループ削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws rds delete-db-subnet-group \
>     --db-subnet-group-name ${DB_SUBNET_GROUP_NAME}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-security-group \
>     --group-id ${RDS_SG_ID}
```
## Redisクラスターを削除する (タブ1)
```bash:コマンド
# Redis クラスター削除
aws elasticache delete-replication-group \
    --replication-group-id ${REPLICATION_GROUP_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # Redis クラスター削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache delete-replication-group \
>     --replication-group-id ${REPLICATION_GROUP_ID}
{
    "ReplicationGroup": {
        "ReplicationGroupId": "elc-tutorial",
        "Description": "Tutorial example",
        "GlobalReplicationGroupInfo": {},
        "Status": "deleting",
        "PendingModifiedValues": {},
        "AutomaticFailover": "enabled",
        "MultiAZ": "enabled",
        "SnapshotRetentionLimit": 0,
        "SnapshotWindow": "13:00-14:00",
        "TransitEncryptionEnabled": false,
        "AtRestEncryptionEnabled": false,
        "ARN": "arn:aws:elasticache:ap-northeast-1:999999999999:replicationgroup:elc-tutorial",
        "LogDeliveryConfigurations": [],
        "ReplicationGroupCreateTime": "2024-08-18T05:35:43.692000+00:00",
        "DataTiering": "disabled",
        "AutoMinorVersionUpgrade": false,
        "NetworkType": "ipv4",
        "IpDiscovery": "ipv4",
        "ClusterMode": "disabled"
    }
}
```
:::note warn
Redis クラスター削除完了までおよそ10分かかる
以後の作業は作成完了後に実施
:::
```bash:コマンド
# キャッシュサブネットグループ削除
aws elasticache delete-cache-subnet-group \
    --cache-subnet-group-name ${CACHESUBNETGROUPNAME}

# セキュリティグループ削除
aws ec2 delete-security-group \
    --group-id ${ELC_SG_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # キャッシュサブネットグループ削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws elasticache delete-cache-subnet-group \
>     --cache-subnet-group-name ${CACHESUBNETGROUPNAME}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # セキュリティグループ削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-security-group \
>     --group-id ${ELC_SG_ID}
[cloudshell-user@ip-10-132-66-
```
## EC2インスタンス削除 (タブ1)
```bash:コマンド
# EC2インスタンス削除
aws ec2 terminate-instances \
    --instance-ids ${EC2_INSTANCE_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # EC2インスタンス削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 terminate-instances \
>     --instance-ids ${EC2_INSTANCE_ID}
{
    "TerminatingInstances": [
        {
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "InstanceId": "i-0fc8f94dd973f6300",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
```
## IAM関連の削除 (タブ1)
```bash:コマンド
# IAMプロファイルのデタッチ
aws iam remove-role-from-instance-profile \
    --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}\
    --role-name ${IAM_ROLE_NAME}

# インスタンスプロファイル削除
aws iam delete-instance-profile \
    --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}

# ロールにアタッチされているポリシーをリスト
IAM_POLICIES_LIST=$(
    aws iam list-attached-role-policies \
        --role-name ${IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${IAM_POLICIES_LIST}

# リスト内のポリシーをデタッチする
for POLICY in ${IAM_POLICIES_LIST}; do
    aws iam detach-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${IAM_ROLE_NAME}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # IAMプロファイルのデタッチ
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam remove-role-from-instance-profile \
>     --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}\
>     --role-name ${IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インスタンスプロファイル削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam delete-instance-profile \
>     --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-66-29 ~]$ IAM_POLICIES_LIST=$(
>     aws iam list-attached-role-policies \
>         --role-name ${IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${IAM_POLICIES_LIST}
arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-66-29 ~]$ for POLICY in ${IAM_POLICIES_LIST}; do
>     aws iam detach-role-policy \
>         --role-name ${IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws iam delete-role \
>     --role-name ${IAM_ROLE_NAME}
```
## VPC削除 (タブ1)
```bash:コマンド
# サブネット削除
aws ec2 delete-subnet --subnet-id ${SUBNET_ID_0}
aws ec2 delete-subnet --subnet-id ${SUBNET_ID_1}
aws ec2 delete-subnet --subnet-id ${SUBNET_ID_2}
aws ec2 delete-subnet --subnet-id ${SUBNET_ID_3}

# ルートテーブル削除
aws ec2 delete-route-table --route-table-id ${RT_ID}

# インターネットゲートウェイデタッチ
aws ec2 detach-internet-gateway \
    --internet-gateway-id ${IGW_ID} \
    --vpc-id ${VPC_ID}

# インターネットゲートウェイ削除
aws ec2 delete-internet-gateway --internet-gateway-id ${IGW_ID}

# VPC削除
aws ec2 delete-vpc --vpc-id ${VPC_ID}

```
```bash:出力
[cloudshell-user@ip-10-132-66-29 ~]$ # サブネット削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-subnet --subnet-id ${SUBNET_ID_0}
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-subnet --subnet-id ${SUBNET_ID_1}
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-subnet --subnet-id ${SUBNET_ID_2}
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-subnet --subnet-id ${SUBNET_ID_3}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # ルートテーブル削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-route-table --route-table-id ${RT_ID}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイデタッチ
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 detach-internet-gateway \
>     --internet-gateway-id ${IGW_ID} \
>     --vpc-id ${VPC_ID}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # インターネットゲートウェイ削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-internet-gateway --internet-gateway-id ${IGW_ID}
[cloudshell-user@ip-10-132-66-29 ~]$ 
[cloudshell-user@ip-10-132-66-29 ~]$ # VPC削除
[cloudshell-user@ip-10-132-66-29 ~]$ aws ec2 delete-vpc --vpc-id ${VPC_ID}
```