1
1

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

Last updated at Posted at 2024-08-24

上記、「ABoosting MySQL database performance with Amazon ElastiCache for Redis」 をAWS CLIでやってみる
image.png
ハンズオンから引用

CloudShellから実施
CloudShellはタブを2つ使用
タブ1:AWS構築用
タブ2:EC2操作用 (Session Manager接続)

事前作業

VPC作成 (タブ1)

ハンズオン用のVPCを作成

変数

コマンド
# 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}

出力
[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作成

コマンド
# 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}

出力
[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

サブネット作成

コマンド
# サブネット作成
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}

出力
[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

インターネットゲートウェイ作成

コマンド
# インターネットゲートウェイ作成
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}

出力
[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}

ルートテーブル作成

コマンド
# ルートテーブル作成
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}

出力
[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)

変数

コマンド
# 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}

出力
[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ロールの作成

コマンド
# 信頼関係ポリシードキュメントの作成
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}

出力
[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ポリシーのアタッチ

コマンド
# 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}

出力
[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)

変数

コマンド
# 名前
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}

出力
[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作成

コマンド
# 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}

出力
[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)

EC2_INSTANCE_IDは適宜変更

コマンド
EC2_INSTANCE_ID=i-0fc8f94dd973f6300

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

出力
[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インストール

コマンド
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

出力
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.

公式ハンズオン上の手順
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

※EC2をamazon linux 2023に変更しているため手順変更

Module 1: Create a Redis Cluster

セキュリティグループ作成 (タブ1)

変数

コマンド
# セキュリティグループ名
ELC_SG_NAME='elc-tutorial-sg' \
&& echo ${ELC_SG_NAME}

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

出力
[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

作成

コマンド
# セキュリティグループ作成
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}

出力
[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)

変数

コマンド
CACHESUBNETGROUPNAME="elc-tutorial-subnet" \
&& echo ${CACHESUBNETGROUPNAME}

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

出力
[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

作成

コマンド
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}

出力
[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)

変数

コマンド
# キャッシュの名前
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}

出力
[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

作成

コマンド
# 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

出力
[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"
    }
}

Redis クラスター作成完了までおよそ15分かかる
以後の作業は作成完了後に実施

確認

コマンド
# レプリケーショングループの詳細
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

出力
[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)

変数

コマンド
# セキュリティグループ名
RDS_SG_NAME='handson-rds-sg' \
&& echo ${RDS_SG_NAME}

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

出力
[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

作成

コマンド
# セキュリティグループ作成
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}

出力
[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)

変数

コマンド
DB_SUBNET_GROUP_NAME='rds-subnet-group' \
&& echo ${DB_SUBNET_GROUP_NAME}

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

出力
[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

作成

コマンド
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}

出力
[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)

変数

コマンド
# 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}

出力
[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

作成

コマンド
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
  
出力
[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"
    }
}

RDS 作成完了までおよそ5分かかる
以後の作業は作成完了後に実施

確認

コマンド
# 詳細確認
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

出力
[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)

変数

RDS_ENDPOINT_ADDRESS、MASTER_USER_PASSWORDは適宜変更

コマンド
RDS_ENDPOINT_ADDRESS="database-1.clacqicsiqrt.ap-northeast-1.rds.amazonaws.com" \
&& echo ${RDS_ENDPOINT_ADDRESS}

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

出力
(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

作成

コマンド
mysql -h ${RDS_ENDPOINT_ADDRESS} -P 3306 -u admin -p${MASTER_USER_PASSWORD} < seed.sql

出力
(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)

変数

コマンド
export ELC_ENDPOINT_ADDRESS=elc-tutorial.veuk10.ng.0001.apne1.cache.amazonaws.com \
&& echo ${ELC_ENDPOINT_ADDRESS}

出力
(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インタプリター起動

コマンド
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.
>>> 

Redis ノードへの接続をテスト

コマンド
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()

出力
>>> 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)

コマンド
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

出力
(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)

スクリプト変更

ハンズオンのスクリプトから変更
(変更点)

  • レコードをキャッシュとデータベースのどちらから取得しているかのメッセージを表示
  • モジュールごとに実行できるように変更
コマンド
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

出力
(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

スクリプト実行

コマンド
python example.py

出力 (キャッシュ無時)
(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'}
出力 (キャッシュ有時)
(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'}

モジュールごとに実行

コマンド
# pythonインタプリター起動
python
出力
(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.
>>> 
コマンド
# モジュールのインポート
from example import fetch
from example import planet

出力
>>> # モジュールのインポート
>>> from example import fetch
>>> from example import planet
コマンド
# fetchの実行
print(fetch("SELECT * FROM planet"))

出力 (キャッシュ無時)
>>> # 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'}]
出力 (キャッシュ有時)
>>> # 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'}]
コマンド
# 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))

出力 (キャッシュ無時)
>>> # 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
出力 (キャッシュ有時)
>>> # 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)

コマンド
exit()

exit

出力
>>> 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)

コマンド
# RDS削除 (タブ1)
aws rds delete-db-instance \
    --db-instance-identifier ${DB_INSTANCE_IDENTIFIER} \
    --skip-final-snapshot \
    --delete-automated-backups \
    --no-cli-pager
    
出力
[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"
    }
}

RDS 削除完了までおよそ5分かかる
以後の作業は作成完了後に実施

コマンド
# 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}

出力
[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)

コマンド
# Redis クラスター削除
aws elasticache delete-replication-group \
    --replication-group-id ${REPLICATION_GROUP_ID}

出力
[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"
    }
}

Redis クラスター削除完了までおよそ10分かかる
以後の作業は作成完了後に実施

コマンド
# キャッシュサブネットグループ削除
aws elasticache delete-cache-subnet-group \
    --cache-subnet-group-name ${CACHESUBNETGROUPNAME}

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

出力
[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)

コマンド
# EC2インスタンス削除
aws ec2 terminate-instances \
    --instance-ids ${EC2_INSTANCE_ID}

出力
[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)

コマンド
# 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}

出力
[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)

コマンド
# サブネット削除
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}

出力
[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}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1