東京リージョンのEC2 Linuxでエレガントにコマンドを実行する ~Amazon EC2 RunCommand~

俺です。

EC2 RunCommandが東京リージョンでも利用できるようになりました。
早速試したいと思います。

参考: [ドキュメント](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/execute-remote-commands.html)

# IAM Roleの準備

SSMに関する[ドキュメント](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ssm-iam.html)からEC2 RunCommandを実行するために必要な権限を定義し、RunCommandを実行するEC2のIAM Role Policyとして適用します

- terraformでポリシーを適用する例

```
resource "aws_iam_role_policy" "ssm-iam-role" {
  name = "ssm-iam-role-policy"
  role = "${aws_iam_role.hogehoge-iam-role.name}"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement" : [
    {
    "Effect": "Allow",
    "Action": [
        "ssm:DescribeAssociation",
        "ssm:GetDocument",
        "ssm:ListAssociations",
        "ssm:UpdateAssociationStatus",
        "ssm:UpdateInstanceInformation"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "ec2messages:AcknowledgeMessage",
        "ec2messages:DeleteMessage",
        "ec2messages:FailMessage",
        "ec2messages:GetEndpoint",
        "ec2messages:GetMessages",
        "ec2messages:SendReply"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "cloudwatch:PutMetricData"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "ec2:DescribeInstanceStatus"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "ds:CreateComputer",
        "ds:DescribeDirectories"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams",
        "logs:PutLogEvents"
    ],
    "Resource": "*"
},
{
    "Effect": "Allow",
    "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts",
        "s3:ListBucketMultipartUploads"
    ],
    "Resource": "*"
}

  ]
}
EOF
}
```
# SSM Agentのインストール

SSM Agentをインストールします。
以下エージェントは東京リージョン用です。

- playbook

```
- name: download EC2 run command
  get_url: url=https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm dest=/tmp/amazon-ssm-agent.rpm
- name: install EC2 run command
  package: name=/tmp/amazon-ssm-agent.rpm state=installed
- name: start ec2 run command service(amazon-ssm-agent)
  service: name=amazon-ssm-agent enabled=yes state=started
```

- ansible-playbook

```
orenomac$ ansible-playbook -i ./inventoryhosts mysql-server.yml
PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [prd-mysql2]
ok: [prd-mysql4]
ok: [prd-mysql1]
ok: [prd-mysql3]
ok: [prd-mysql5]
ok: [prd-mysql6]

TASK [include] *****************************************************************
included: /ansible/roles/amazonlinux_init/tasks/ec2_runcommand.yml for prd-mysql1, prd-mysql2, prd-mysql3, prd-mysql4, prd-mysql5, prd-mysql6

TASK [download EC2 run command] ************************************************
ok: [prd-mysql2]
ok: [prd-mysql4]
ok: [prd-mysql3]
ok: [prd-mysql5]
ok: [prd-mysql1]
ok: [prd-mysql6]

TASK [install EC2 run command] *************************************************
changed: [prd-mysql4]
changed: [prd-mysql1]
changed: [prd-mysql2]
changed: [prd-mysql5]
changed: [prd-mysql3]
changed: [prd-mysql6]

TASK [start ec2 run command service(amazon-ssm-agent)] *************************
ok: [prd-mysql2]
ok: [prd-mysql4]
ok: [prd-mysql1]
ok: [prd-mysql3]
ok: [prd-mysql5]
ok: [prd-mysql6]

PLAY RECAP *********************************************************************
prd-mysql1                 : ok=5    changed=1    unreachable=0    failed=0
prd-mysql2                 : ok=5    changed=1    unreachable=0    failed=0
prd-mysql3                 : ok=5    changed=1    unreachable=0    failed=0
prd-mysql4                 : ok=5    changed=1    unreachable=0    failed=0
prd-mysql5                 : ok=5    changed=1    unreachable=0    failed=0
prd-mysql6                 : ok=5    changed=1    unreachable=0    failed=0
```

# AWSコンソールからEC2 RunCommandの実行

## 実行ホストの選択とコマンド準備

俺の大好きslコマンドをインストールして、実行します。

<img width="1288" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42755/61501ddd-2ba2-e5b8-914f-ac8037209c75.png">

## EC2 RunCommandの実行

選択したEC2インスタンスに対してEC2 RunCommandのCommandsが発行されました。

<img width="1036" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/42755/e1744ada-32f2-dfc2-4c10-b6f188efe006.png">

## 実行結果の確認

なんと `Failed` です。
EC2 RunCommandで `sl` コマンドはfailします。

<img width="1270" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/42755/458f781a-9e17-8798-915a-a3f371d71545.png">


ネタでしか無いのですが、便利だなーと思いました。
レッツエンジョイ。

おわり。