boto3を使用してEC2立ち上げに必要な環境構築を行う

2020.05.31

こんにちは、最近AWS CLIやboto3にハマってる下地です。

AWS CLIの操作に関して下記サイトの手順通りに実装することでVPCからEC2の作成を行いssh接続できる環境を作成することができます。今回は、この内容をboto3を使用して実装したいと思います。

例: AWS CLI を使用して IPv4 VPC とサブネットを作成

環境

実行は環境は下記のようになります。

  • MacOS: Catalina 10.15.4
  • Python: 3.7.0
  • Boto3: 1.12.33

作成手順

公式サイトを参考に下記の手順で実装していきます。

  1. 必要な関数のimport
  2. VPCとサブネットを作成する
  3. サブネットをパブリックにする
  4. サブネット内にインスタンスを起動する
  5. 接続確認を行う
  6. クリーンアップする

1. 必要な関数のimport

まずはじめに、必要な関数をimportします。私の環境ではスイッチロールしたアカウントで操作する必要があったため下記リンクを参考に設定しました。

スイッチロールしたIAM RoleをPython Boto3で使いたい

from boto3.session import Session
session = Session(profile_name= *****)
client = session.client("ec2")

2. VPCとサブネットを作成する

10.0.0.0/16のCIDRブロックをを持つVPCを作成します。作成後にVPCのidを取得します。

# VPCの作成
vpc = client.create_vpc(CidrBlock='10.0.0.0/16',)
vpc_id = vpc['Vpc']['VpcId']

作成したVPCに、10.0.0.0/24のCIDR ブロックを持つサブネットを作成します。

# subnetの作成
subnet = client.create_subnet(
    AvailabilityZone='ap-northeast-1a',
    CidrBlock='10.0.0.0/24',
    VpcId=vpc_id)
subnet_id = subnet['Subnet']['SubnetId']

3. サブネットをパブリックにする

作成したサブネットをパブリックサブネットにするには、インターネットゲートウェイ(igw)を作成しVPCにアタッチします。そして、カスタムルートテーブルを作成し、igwへのサブネットのルーティングを構成する必要があります。

まずigwを作成を行いigwのidを取得します。そして、作成したVPCにigwをアタッチします。

#igwの作成とigwのidを取得
internet_gateway = client.create_internet_gateway()
igw_id = internet_gateway['InternetGateway']['InternetGatewayId']

#igwをVPCにアタッチする
attach_igw_to_vpc = client.attach_internet_gateway(InternetGatewayId=igw_id, VpcId=vpc_id)

次に、カスタムルートテーブルを作成します。

#カスタムルートテーブルを作成しidを取得する
route_table = client.create_route_table(VpcId=vpc_id)
route_table_id = route_table['RouteTable']['RouteTableId']

igwへのすべてのトラフィック (0.0.0.0/0) をポイントするルートテーブルでルートを作成します。

#ルートを作成
create_route = client.create_route(
    DestinationCidrBlock='0.0.0.0/0',
    GatewayId=igw_id, 
    RouteTableId=route_table_id)

ルートテーブルはサブネットには関連付けられていませんので関連づけます。関連づけたidを取得します。

associate_route_table = client.associate_route_table(
    RouteTableId=route_table_id,
    SubnetId=subnet_id)
rt_associationId = associate_route_table['AssociationId']

サブネット内で起動されたインスタンスがパブリックIPアドレスを自動的に受信できるように設定します。

modify_subnet_attribute = client.modify_subnet_attribute(
    MapPublicIpOnLaunch={'Value': True},
    SubnetId=subnet_id)

4. サブネット内にインスタンスを起動する

パブリックサブネットまで作成できました。EC2を作成しssh接続するにセキュリティグループ(sg)とキーペアが必要ですので作成します。

sgを新しく作成しidを取得します。そして、ssh接続のための22ポートの接続を設定します。

#セキュリティグループを作成する
security_group = client.create_security_group(
    Description='test-from-boto3',
    GroupName='test-from-boto3',
    VpcId=vpc_id)
security_id = security_group['GroupId']

my_ip = '*.*.*.*/**'
#my_ipからの22番ポートへの接続を設定する
authorize_ssh = client.authorize_security_group_ingress(
    GroupId=security_id,
    IpPermissions=[
        {
            'FromPort': 22,
            'IpProtocol': 'tcp',
            'IpRanges': [
                {
                    'CidrIp': my_ip,
                    'Description': 'SSH access from the cm office',
                },
            ],
            'ToPort': 22,
        },
    ],
)

次にキーペアの作成を行います。キーペアの情報が戻り値として返りますのでpemファイルを作成します。

key_name = 'make-from-boto3'

#キーペアを作成する
key_pair = client.create_key_pair(KeyName=key_name,)

#キーペアの情報を取得して pemファイルを作成する
meta_data = key_pair['KeyMaterial']
path = key_name + '.pem'
with open(path, mode='w') as f:
    f.write(meta_data)

これで必要な設定が完了しましたので、EC2のインスタンスを立ち上げます。

image_id = 'ami-0f310fced6141e627' #インスタンスのid
key_id = 'Name'
key_value = 'test_from_boto3'

#ec2インスタンスを作成
instance = client.run_instances(
    ImageId=image_id,
    MinCount=1,
    MaxCount=1,
    InstanceType="t2.micro",
    KeyName=key_name,
    SecurityGroupIds=[security_id],
    SubnetId=subnet_id,
    TagSpecifications=[
        {
            'ResourceType': 'instance',
            'Tags': [
                {
                    'Key': key_id,
                    'Value': key_value
                },
            ]
        },
    ],
)

EC2が作成されました。作成完了まで少し時間をおき作成したEC2のパブリックIPアドレスを確認します。

#作成したインスタンスのidを取得する
instanceId = instance['Instances'][0]['InstanceId']

#インスタンスの詳細
instance_public_ip = client.describe_instances(InstanceIds=[instanceId])

#詳細データの中からpublicアドレスを確認する
ec2_public_ip_address = instance_public_ip['Reservations'][0]['Instances'][0]['PublicIpAddress']
print(ec2_public_ip_address)

詳細の情報からパブリックIPアドレスを確認できます。

5. ssh接続確認

EC2のパブリックIPアドレスの確認までできましたので取得したEC2のパブリックIPアドレスを使用して接続確認を行います。

先ほど作成した、キーペアがあるディレクトリに移動します。そして、キーペア名とパブリックipアドレスを指定してssh接続します。

$  ssh -i make-from-boto3.pem ec2-user@**.***.***.***

[ec2-user@ip-**-*-*-*** ~]$ 

インスタンスに接続することが確認できました。

6. クリーンアップする

では最後に後片付けをします。依存関係がありますので構築と逆の順番で削除していきます。

#EC2の削除
delete_ec2 = client.terminate_instances(InstanceIds=[instanceId,])

#セキュリティグループの削除
delete_sg = client.delete_security_group(GroupId=security_id)

# AssociationIdを解除する
disassociate_route = client.disassociate_route_table(AssociationId=rt_associationId)

# ルートテーブルの削除
delete_rt = client.delete_route_table(RouteTableId=route_table_id)

#igwをvpcからデタッチする
detach_igw = client.detach_internet_gateway(
        InternetGatewayId=igw_id, VpcId=vpc_id)

#igwの削除
delete_igw = client.delete_internet_gateway(InternetGatewayId=igw_id)

#サブネットを削除
delete_sub = client.delete_subnet(SubnetId=subnet_id)

#vpcを削除
delete_vpc = client.delete_vpc(VpcId=vpc_id)

#キーペアの削除
delete_key = client.delete_key_pair(KeyName=key_name)

まとめ

AWS CLIのチュートリアルがあるならboto3でも出来そうだとコマンドを探すとありましたのでboto3でVPCの作成からEC2の立ち上げまで実装しました。boto3はとっても便利ですので使ってみたいと思ってる方の助けになれば幸いです。

参考リンク