マネジメントコンソールを使わずAWS CLI だけで VPC とサブネットを作成してさらにインスタンスの起動もしてSSHで接続する

いい感じのチュートリアルを見つけたのでやってみました。
構成図も書いてみました。

例: AWS CLI を使用して IPv4 VPC とサブネットを作成
https://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-subnets-commands-example.html

## 完成形

![Step3.png](https://qiita-image-store.s3.amazonaws.com/0/41574/df6b2dad-796c-ee01-ee34-9fce250feb86.png)


# 環境
Windows 10
AWS CLI 1.15.10

## AWS CLIのプロファイルを作成

`qiita`という名前のプロファイルを作成。リージョンは東京にしました。

```shell
aws configure --profile qiita
```

```console
AWS Access Key ID [None]:           <--- Access Keyを入力
AWS Secret Access Key [None]:       <--- Secret Access Keyを入力
Default region name [None]:         <--- ap-northeast-1を入力
Default output format [None]:       <--- 未入力
```

```shell
aws configure list --profile qiita
```

```console
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                    qiita           manual    --profile
access_key     ****************PLCA shared-credentials-file
secret_key     ****************rObp shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

# ステップ 1: VPC とサブネットを作成する

## AWS CLI を使用して VPC およびサブネットを作成するには

* 10.0.0.0/16 CIDR ブロックを持つ VPC を作成します。

```shell
aws ec2 create-vpc --cidr-block 10.0.0.0/16 --profile qiita
```

```console
{
    "Vpc": {
        "VpcId": "vpc-29b62c4e",
        "InstanceTenancy": "default",
        "Tags": [],
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-4850cf20",
                "CidrBlock": "10.0.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "Ipv6CidrBlockAssociationSet": [],
        "State": "pending",
        "DhcpOptionsId": "dopt-b3268cd6",
        "CidrBlock": "10.0.0.0/16",
        "IsDefault": false
    }
}
```

* 前の手順の VPC IDを使用して、10.0.1.0/24 CIDR ブロックを持つサブネットを作成します。

```shell
aws ec2 create-subnet --vpc-id vpc-29b62c4e --cidr-block 10.0.1.0/24 --profile qiita
```

```console
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1d",
        "AvailableIpAddressCount": 251,
        "DefaultForAz": false,
        "Ipv6CidrBlockAssociationSet": [],
        "VpcId": "vpc-29b62c4e",
        "State": "pending",
        "MapPublicIpOnLaunch": false,
        "SubnetId": "subnet-30eeea18",
        "CidrBlock": "10.0.1.0/24",
        "AssignIpv6AddressOnCreation": false
    }
}
```

* VPC で、10.0.0.0/24 CIDR ブロックを持つ 2 番目のサブネットを作成します。

```shell
aws ec2 create-subnet --vpc-id vpc-29b62c4e --cidr-block 10.0.0.0/24 --profile qiita
```

```console
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1d",
        "AvailableIpAddressCount": 251,
        "DefaultForAz": false,
        "Ipv6CidrBlockAssociationSet": [],
        "VpcId": "vpc-29b62c4e",
        "State": "pending",
        "MapPublicIpOnLaunch": false,
        "SubnetId": "subnet-45ede96d",
        "CidrBlock": "10.0.0.0/24",
        "AssignIpv6AddressOnCreation": false
    }
}
```

## 構成図

![Step1.png](https://qiita-image-store.s3.amazonaws.com/0/41574/d510a19d-23e6-b2e0-3a95-b33d1052dd34.png)

ステップ2のカスタムルートテーブルを作ってないと、デフォルトのルートテーブルが作成されるようです。

# ステップ2: サブネットをパブリックにします。

## サブネットをパブリックサブネットにするには

* インターネットゲートウェイを作成する.

```shell
aws ec2 create-internet-gateway --profile qiita
```

```console
{
    "InternetGateway": {
        "Tags": [],
        "Attachments": [],
        "InternetGatewayId": "igw-9eda9dfa"
    }
}
```

* 前のステップの ID を使用して、VPC にインターネットゲートウェイをアタッチします。

```shell
aws ec2 attach-internet-gateway --vpc-id vpc-29b62c4e --internet-gateway-id igw-9eda9dfa --profile qiita
```

```console
```

* VPC に対してカスタムルートテーブルを作成します。

```shell
aws ec2 create-route-table --vpc-id vpc-29b62c4e --profile qiita
```

```console
{
    "RouteTable": {
        "Associations": [],
        "RouteTableId": "rtb-67c92101",
        "VpcId": "vpc-29b62c4e",
        "PropagatingVgws": [],
        "Tags": [],
        "Routes": [
            {
                "GatewayId": "local",
                "DestinationCidrBlock": "10.0.0.0/16",
                "State": "active",
                "Origin": "CreateRouteTable"
            }
        ]
    }
}
```

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

```shell
aws ec2 create-route --route-table-id rtb-67c92101 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-9eda9dfa --profile qiita
```

```console
{
    "Return": true
}
```

* ルートが作成され有効になっていることを確認するには、ルートテーブルを記述して結果を表示できます。

```shell
aws ec2 describe-route-tables --route-table-id rtb-67c92101 --profile qiita
```

```console
{
    "RouteTables": [
        {
            "Associations": [],
            "RouteTableId": "rtb-67c92101",
            "VpcId": "vpc-29b62c4e",
            "PropagatingVgws": [],
            "Tags": [],
            "Routes": [
                {
                    "GatewayId": "local",
                    "DestinationCidrBlock": "10.0.0.0/16",
                    "State": "active",
                    "Origin": "CreateRouteTable"
                },
                {
                    "GatewayId": "igw-9eda9dfa",
                    "DestinationCidrBlock": "0.0.0.0/0",
                    "State": "active",
                    "Origin": "CreateRoute"
                }
            ]
        }
    ]
}
```

* ルートテーブルは現在、サブネットには関連付けられていません。サブネットからのトラフィックがインターネットゲートウェイにルーティングされるよう、ルートテーブルを VPC のサブネットに関連付ける必要があります。最初に、describe-subnets コマンドを使用してサブネット ID を取得します。--filter オプションを使用して新しい VPC のサブネットだけを返し、--query オプションを使用してサブネット ID と CIDR ブロックだけを返します。

```shell
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-29b62c4e" --query 'Subnets[*].{ID:SubnetId,CIDR:CidrBlock}' --profile qiita
```

```console
"Subnets[*].{ID:SubnetId,CIDR:CidrBlock}"
```

queryすると結果が出ない。。Windowsだとだめなのかな

```shell
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-29b62c4e" --profile qiita
```

```console
{
    "Subnets": [
        {
            "AvailabilityZone": "ap-northeast-1d",
            "AvailableIpAddressCount": 251,
            "DefaultForAz": false,
            "Ipv6CidrBlockAssociationSet": [],
            "VpcId": "vpc-29b62c4e",
            "State": "available",
            "MapPublicIpOnLaunch": false,
            "SubnetId": "subnet-30eeea18",
            "CidrBlock": "10.0.1.0/24",
            "AssignIpv6AddressOnCreation": false
        },
        {
            "AvailabilityZone": "ap-northeast-1d",
            "AvailableIpAddressCount": 251,
            "DefaultForAz": false,
            "Ipv6CidrBlockAssociationSet": [],
            "VpcId": "vpc-29b62c4e",
            "State": "available",
            "MapPublicIpOnLaunch": false,
            "SubnetId": "subnet-45ede96d",
            "CidrBlock": "10.0.0.0/24",
            "AssignIpv6AddressOnCreation": false
        }
    ]
}
```

* カスタムルートテーブルに関連付けるサブネット、例えば subnet-b46032ec を選択できます。このサブネットはパブリックサブネットになります。

```shell
aws ec2 associate-route-table  --subnet-id subnet-30eeea18 --route-table-id rtb-67c92101 --profile qiita
```

```console
{
    "AssociationId": "rtbassoc-b44659d2"
}
```

* サブネット内で起動されたインスタンスがパブリック IP アドレスを自動的に受信できるよう、オプションで、サブネットの動作に対処しているパブリック IP を変更できます。これを行わない場合は、インターネットからインスタンスにアクセスできるよう、起動後に Elastic IP アドレスをインスタンスに関連付ける必要があります。

```shell
aws ec2 modify-subnet-attribute --subnet-id subnet-30eeea18 --map-public-ip-on-launch --profile qiita
```

```console
```

もう一度サブネットの情報を取得

```shell
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-29b62c4e" --profile qiita
```

```console
{
    "Subnets": [
        {
            "AvailabilityZone": "ap-northeast-1d",
            "AvailableIpAddressCount": 251,
            "DefaultForAz": false,
            "Ipv6CidrBlockAssociationSet": [],
            "VpcId": "vpc-29b62c4e",
            "State": "available",
            "MapPublicIpOnLaunch": true,
            "SubnetId": "subnet-30eeea18",
            "CidrBlock": "10.0.1.0/24",
            "AssignIpv6AddressOnCreation": false
        },
        {
            "AvailabilityZone": "ap-northeast-1d",
            "AvailableIpAddressCount": 251,
            "DefaultForAz": false,
            "Ipv6CidrBlockAssociationSet": [],
            "VpcId": "vpc-29b62c4e",
            "State": "available",
            "MapPublicIpOnLaunch": false,
            "SubnetId": "subnet-45ede96d",
            "CidrBlock": "10.0.0.0/24",
            "AssignIpv6AddressOnCreation": false
        }
    ]
}
```

`subnet-30eeea18`の`MapPublicIpOnLaunch`が`true`になってますね。

## 構成図

![Step2.png](https://qiita-image-store.s3.amazonaws.com/0/41574/73467ad8-d407-be21-ff65-1b5d9bafac93.png)

ルートテーブルが２つになって、インターネットにアクセスできるサブネットとできないサブネットができました。

# ステップ 3: サブネット内にインスタンスを起動する

## パブリックサブネット内のインスタンスを起動して接続するには

* キーペアを作成して、--query オプションと --output テキストオプションを使用し、.pem 拡張機能でプライベートキーをファイルに直接パイプします。
※これもqueryが上手くいかない。。。

```shell
aws ec2 create-key-pair --key-name MyKeyPair --output text --profile qiita
```

```console
ff:5b:2d:43:fa:cd:1e:f2:30:8a:fd:7a:38:6a:48:70:bc:ff:99:d1     -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAnqussaU7076k4d56v4Wz5PpZDCfgKKTWTtCsoBD3nzyR6moFRzFAlZ2qi1Tq
(省略)
EZss5GqDXov5B23iXcK9E9iRSnyPNVxDHmM240eHOMKTZkoLog+jnEQhG9Y6pTaHJAM=
-----END RSA PRIVATE KEY-----   MyKeyPair

```

`-----BEGIN RSA PRIVATE KEY-----`から`-----END RSA PRIVATE KEY-----`までをコピーしてテキストファイルに保存します。

* VPC にセキュリティグループを作成し、SSH でどこからでもアクセスできるようにするルールを追加します。

```shell
aws ec2 create-security-group --group-name SSHAccess --description "Security group for SSH access" --vpc-id vpc-29b62c4e --profile qiita
```

```console
{
    "GroupId": "sg-1846be60"
}
```

```shell
aws ec2 authorize-security-group-ingress --group-id sg-1846be60 --protocol tcp --port 22 --cidr 0.0.0.0/0 --profile qiita
```

```console
```

* 作成したセキュリティグループとキーペアを使用して、パブリックサブネット内でインスタンスを起動します。出力内のインスタンスのインスタンス ID をメモしておきます。

※AMI IDはここでわかります。
https://aws.amazon.com/jp/amazon-linux-ami/

```shell
aws ec2 run-instances --image-id ami-ceafcba8	--count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-1846be60 --subnet-id subnet-30eeea18  --profile qiita
```

```console
{
    "Instances": [
        {
            "Monitoring": {
                "State": "disabled"
            },
            "PublicDnsName": "",
            "StateReason": {
                "Message": "pending",
                "Code": "pending"
            },
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "EbsOptimized": false,
            "LaunchTime": "2018-04-30T02:17:53.000Z",
            "PrivateIpAddress": "10.0.1.119",
            "ProductCodes": [],
            "VpcId": "vpc-29b62c4e",
            "StateTransitionReason": "",
            "InstanceId": "i-0b192396791d0afa0",
            "ImageId": "ami-ceafcba8",
            "PrivateDnsName": "ip-10-0-1-119.ap-northeast-1.compute.internal",
            "KeyName": "MyKeyPair",
            "SecurityGroups": [
                {
                    "GroupName": "SSHAccess",
                    "GroupId": "sg-1846be60"
                }
            ],
            "ClientToken": "",
            "SubnetId": "subnet-30eeea18",
            "InstanceType": "t2.micro",
            "NetworkInterfaces": [
                {
                    "Status": "in-use",
                    "MacAddress": "0e:ca:57:b1:d0:d8",
                    "SourceDestCheck": true,
                    "VpcId": "vpc-29b62c4e",
                    "Description": "",
                    "NetworkInterfaceId": "eni-b22fa5ac",
                    "PrivateIpAddresses": [
                        {
                            "Primary": true,
                            "PrivateIpAddress": "10.0.1.119"
                        }
                    ],
                    "SubnetId": "subnet-30eeea18",
                    "Attachment": {
                        "Status": "attaching",
                        "DeviceIndex": 0,
                        "DeleteOnTermination": true,
                        "AttachmentId": "eni-attach-a9d214cf",
                        "AttachTime": "2018-04-30T02:17:53.000Z"
                    },
                    "Groups": [
                        {
                            "GroupName": "SSHAccess",
                            "GroupId": "sg-1846be60"
                        }
                    ],
                    "Ipv6Addresses": [],
                    "OwnerId": "781749372177",
                    "PrivateIpAddress": "10.0.1.119"
                }
            ],
            "SourceDestCheck": true,
            "Placement": {
                "Tenancy": "default",
                "GroupName": "",
                "AvailabilityZone": "ap-northeast-1d"
            },
            "Hypervisor": "xen",
            "BlockDeviceMappings": [],
            "Architecture": "x86_64",
            "RootDeviceType": "ebs",
            "RootDeviceName": "/dev/xvda",
            "VirtualizationType": "hvm",
            "AmiLaunchIndex": 0
        }
    ],
    "ReservationId": "r-0aedd8269b2d255bd",
    "Groups": [],
    "OwnerId": "781749372177"
}
```

* インスタンスに接続するには、そのインスタンスが running 状態になっている必要があります。インスタンスを記述してその状態を確認し、パブリック IP アドレスを書き留めておきます。

```shell
aws ec2 describe-instances --instance-id i-0b192396791d0afa0 --profile qiita
```

```console
{
    "Reservations": [
        {
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "EbsOptimized": false,
                    "LaunchTime": "2018-04-30T02:17:53.000Z",
                    "PublicIpAddress": "18.182.20.38",
                    "PrivateIpAddress": "10.0.1.119",
                    "ProductCodes": [],
                    "VpcId": "vpc-29b62c4e",
                    "StateTransitionReason": "",
                    "InstanceId": "i-0b192396791d0afa0",
                    "EnaSupport": true,
                    "ImageId": "ami-ceafcba8",
                    "PrivateDnsName": "ip-10-0-1-119.ap-northeast-1.compute.internal",
                    "KeyName": "MyKeyPair",
                    "SecurityGroups": [
                        {
                            "GroupName": "SSHAccess",
                            "GroupId": "sg-1846be60"
                        }
                    ],
                    "ClientToken": "",
                    "SubnetId": "subnet-30eeea18",
                    "InstanceType": "t2.micro",
                    "NetworkInterfaces": [
                        {
                            "Status": "in-use",
                            "MacAddress": "0e:ca:57:b1:d0:d8",
                            "SourceDestCheck": true,
                            "VpcId": "vpc-29b62c4e",
                            "Description": "",
                            "NetworkInterfaceId": "eni-b22fa5ac",
                            "PrivateIpAddresses": [
                                {
                                    "PrivateIpAddress": "10.0.1.119",
                                    "Primary": true,
                                    "Association": {
                                        "PublicIp": "18.182.20.38",
                                        "PublicDnsName": "",
                                        "IpOwnerId": "amazon"
                                    }
                                }
                            ],
                            "SubnetId": "subnet-30eeea18",
                            "Attachment": {
                                "Status": "attached",
                                "DeviceIndex": 0,
                                "DeleteOnTermination": true,
                                "AttachmentId": "eni-attach-a9d214cf",
                                "AttachTime": "2018-04-30T02:17:53.000Z"
                            },
                            "Groups": [
                                {
                                    "GroupName": "SSHAccess",
                                    "GroupId": "sg-1846be60"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "OwnerId": "781749372177",
                            "PrivateIpAddress": "10.0.1.119",
                            "Association": {
                                "PublicIp": "18.182.20.38",
                                "PublicDnsName": "",
                                "IpOwnerId": "amazon"
                            }
                        }
                    ],
                    "SourceDestCheck": true,
                    "Placement": {
                        "Tenancy": "default",
                        "GroupName": "",
                        "AvailabilityZone": "ap-northeast-1d"
                    },
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": true,
                                "VolumeId": "vol-06f8f3fc34c17685d",
                                "AttachTime": "2018-04-30T02:17:54.000Z"
                            }
                        }
                    ],
                    "Architecture": "x86_64",
                    "RootDeviceType": "ebs",
                    "RootDeviceName": "/dev/xvda",
                    "VirtualizationType": "hvm",
                    "AmiLaunchIndex": 0
                }
            ],
            "ReservationId": "r-0aedd8269b2d255bd",
            "Groups": [],
            "OwnerId": "781749372177"
        }
    ]
}
```

## 構成図

![Step3.png](https://qiita-image-store.s3.amazonaws.com/0/41574/665dfbac-2822-f543-cac8-75ac9cc736f4.png)

インターネット側へのアクセスが可能で、外部の任意のIPアドレスからのSSH接続が可能なインスタンスが起動しました。

# 手順 4: クリーンアップ

* インスタンスを終了

```shell
aws ec2 terminate-instances --instance-id i-0b192396791d0afa0 --profile qiita
```

```console
{
    "TerminatingInstances": [
        {
            "InstanceId": "i-0b192396791d0afa0",
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
```

* セキュリティグループを削除する:

```shell
aws ec2 delete-security-group --group-id sg-1846be60 --profile qiita
```

```console
```

* サブネットを削除する:

```shell
aws ec2 delete-subnet --subnet-id subnet-30eeea18 --profile qiita
```

```console
```

```shell
aws ec2 delete-subnet --subnet-id subnet-45ede96d --profile qiita
```

```console
```

* カスタムルートテーブルを削除する:

```shell
aws ec2 delete-route-table --route-table-id rtb-67c92101 --profile qiita
```

```console
```

* VPC からのインターネットゲートウェイのデタッチ:

```shell
aws ec2 detach-internet-gateway --internet-gateway-id igw-9eda9dfa --vpc-id vpc-29b62c4e --profile qiita
```

```console
```

* インターネットゲートウェイの削除:

```shell
aws ec2 delete-internet-gateway --internet-gateway-id igw-9eda9dfa --profile qiita
```

```console
```

* VPC の削除:

```shell
aws ec2 delete-vpc --vpc-id vpc-29b62c4e --profile qiita
```

```console
```

# 終わりに

次はCloudFormationに挑戦しようと思います。