LoginSignup
5
3

More than 5 years have passed since last update.

AWS CLI で json 使って EC2 をいじる

Last updated at Posted at 2018-12-14

ちょうど今AWS環境におけるサーバ構築の効率化を進めているので、
使っている AWS CLI をまとめたいと思います。

前提

aws cli のインストール、認証情報の登録は済んでいることとする。
使用するAMIは準備済み。

EC2インスタンス作成

最初に AWS CLI でインスタンスを作成してみる。
AWS CLI は json形式で設定値を流し込むことが出来ます。
--generate-cli-skeleton オプションで jsonファイルのひな型を出力することが出来るので以下を実行。

aws ec2 run-instances --generate-cli-skeleton

jsonファイルが出力されるので、それを基に以下のような感じで指定したい項目を埋めていく。
※適宜必要な項目を埋めて下さい。

ec2.json
{
    "BlockDeviceMappings": [
        {
            "DeviceName": "/dev/sda1",
            "VirtualName": "${InstanceName}",
            "Ebs": {
                "DeleteOnTermination": true,
                "VolumeSize": 40,
                "VolumeType": "gp2"
            },
            "NoDevice": ""
        }
    ],
    "ImageId": "${AMIID}",
    "InstanceType": "t2.micro",
    "MaxCount": 1,
    "MinCount": 1,
    "Monitoring": {
        "Enabled": false
    },
    "Placement": {
        "AvailabilityZone": "ap-northeast-1d"
    },
    "SubnetId": "${SubnetID}",
    "UserData": "",
    "AdditionalInfo": "",
    "DisableApiTermination": true,
    "DryRun": false,
    "IamInstanceProfile": {
        "Name": "${RoleName}"
    },
    "InstanceInitiatedShutdownBehavior": "stop",
    "NetworkInterfaces": [
        {
            "AssociatePublicIpAddress": true,
            "DeleteOnTermination": true,
            "Description": "",
            "DeviceIndex": 0,
            "Groups": [
                "${SecurityGroupID}"
            ],
            "PrivateIpAddresses": [
                {
                    "Primary": true,
                    "PrivateIpAddress": "173.16.0.5"
                }
            ],
            "SubnetId": "${SubnetID}"
        }
    ],
    "TagSpecifications": [
        {
            "ResourceType": "instance",
            "Tags": [
                {
                    "Value": "${任意の値}",
                    "Key": "${任意のキー}"
                },
                {
                    "Value": "${任意の値}",
                    "Key": "${任意のキー}"
                }
            ]
        },
        {
            "ResourceType": "volume",
            "Tags": [
                {
                    "Value": "${任意の値}",
                    "Key": "${任意のキー}"
                },
                {
                    "Value": "${任意の値}",
                    "Key": "${任意のキー}"
                }
            ]
        }
    ]
}
  • VirtualName ... インスタンス名
  • VolumeSize ... EBSボリュームサイズ
  • VolumeType ... EBSボリュームタイプ
  • DeleteOnTermination ... インスタンス削除時にEBSボリュームも一緒に削除するかどうか
  • ImageId ... ベースとなるAMI ID を指定
  • DisableApiTermination ... 削除保護の有無
  • IamInstanceProfile ... IAMロール名
  • Groups ... セキュリティグループ名
  • PrivateIpAddress ... プライベートIPアドレス
  • SubnetId ... サブネットID
  • TagSpecifications ... タグの指定(上記の例ではインスタンスとボリュームの両方に2つずつタグをつけている)

で、それを --cli-input-json で指定すればOK


aws ec2 run-instances --cli-input-json file:///path/to/dir/ec2.json

※jsonファイルは file:// で指定しないと以下のようなエラーになるので注意。

[エラー文言]
Error parsing parameter 'cli-input-json': Invalid JSON: No JSON object could be decoded

これでインスタンスが作成されます。

EIP取得

次は、EIPを取得してさっき作成したインスタンスに紐づけてみる。
まずは、EIPを取得。
※ --output text は特定の値を取りたいときに便利です。以下の場合は AllocationID が戻り値で取れます。

aws ec2 allocate-address --domain vpc --query AllocationId --output text

そして、紐付けたい AllocationID と InstanceID を指定すればOK

aws ec2 associate-address --allocation-id ${AllocationID} --instance ${InstanceID}

これで作成したインスタンスにEIPが紐づきました。

SecurityGroup作成

次は、セキュリティグループの作成から、ルールの追加、インスタンスへの紐づけをやってみる。
これも json ファイルを出力する。

aws ec2 create-security-group --generate-cli-skeleton

少ないからオプションで指定してもいいかもしれないが、せっかくだから --cli-input-json でやりたい。

securitygroup.json
{
    "Description": "${Description}", 
    "GroupName": "${SecurityGroupName}", 
    "VpcId": "${VPCID}"
}
  • Description ... 説明
  • GroupName ... セキュリティグループ名
  • VpcId ... VPC ID

こんな感じで値を入れて、以下の通り実行。
※ --output text を入れているので戻り値は SecurityGroupID

aws ec2 create-security-group --cli-input-json file:///path/to/dir/securitygroup.json --output text

そして、作ったセキュリティグループにルールを追加。
これもまずは json 出力して

aws ec2 authorize-security-group-ingress --generate-cli-skeleton

必要な値を入れて

rule.json
{
    "GroupId": "${SecurityGroupID}", 
    "IpPermissions": [
        {
            "FromPort": 0, 
            "IpProtocol": "tcp", 
            "IpRanges": [
                {
                    "CidrIp": "173.16.0.5/32", 
                    "Description": ""
                }
            ], 
            "FromPort": 22,
            "ToPort": 22
        }
    ],
    "DryRun": false
}
  • GroupId ... セキュリティグループID
  • CidrIp ... ソースIP
  • FromPort,ToPort ... ポート範囲

以下の通り実行。

aws ec2 authorize-security-group-ingress --cli-input-json file:///path/to/dir/rule.json

これでセキュリティグループが作成できたので、インスタンスに適用してみよう。

aws ec2 modify-instance-attribute --group ${SecurityGroupID} --instance-id ${InstanceID}

既にセキュリティグループが設定されているインスタンスの場合は置き換わってしまうので注意!
--group で指定したセキュリティグループのみになってしまうので、追加したい場合は下記のようにスペース区切りで複数指定して下さい。

aws ec2 modify-instance-attribute --group ${SecurityGroupID} ${SecurityGroupID} --instance-id ${InstanceID}

running になるまで待つ

EIPの紐づけにしても、セキュリティグループの紐づけにしても、
インスタンスの状態が running にならないと以下のようなエラーになってしまう。

An error occurred (InvalidInstanceID) when calling the AssociateAddress operation: The pending instance '${InstanceID}' is not in a valid state for this operation.

なので、一連の処理をシェルスクリプト等でまとめてやろうとすると、
インスタンス状態の判定が必要になる。

僕は以下のようにインスタンスの状態を判定していたのだが、、

STATE=`aws ec2 describe-instances --instance-ids ${InstanceID} --query 'Reservations[*].Instances[*].State[].Name' --output text`
while [ $STATE != "running" ]
do
        sleep 5
        STATE=`aws ec2 describe-instances --instance-ids ${InstanceID} --query 'Reservations[*].Instances[*].State[].Name' --output text`
done

こんなことせずとも、以下でステータスの状態が running になるまで待ってくれます。。

aws ec2 wait instance-running --instance-ids ${InstanceID}

ちなみに、wait は他にも色んなオプションがあるので何かと便利。
例えば、システムチェックが終わるのを待ちたい場合はこれ。

aws ec2 wait instance-status-ok --instance-ids ${InstanceID}

:christmas_tree: FORK Advent Calendar 2018
:arrow_left: 18日目 ちょっとかわいいBrainF*ck @sunnyplace
:arrow_right: 19日目 git clone できない時の調べ方と対策 @izanari

5
3
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
5
3