EC2 Run Command and SSM Agent


EC2 Run Command 是用來執行遠端指令,管理 EC2 Instance、或者自己的 VM (on-primises) ,可以執行像是 Unix Scripts 和 Windows PowerShell 等。

SSM 全名是 Amazon EC2 Simple Systems Manager (SSM),主要就是用來控管 EC2 的代理程式,透過他可以自動化很多維運任務,常見的像是 Windows Update、SSM Agent Upgrade、Remote Script (bash or powershell),也可以做像是 CodeDeploy 的事情,然後用來做 CD。

EC2 Run Command & SSM Agent 不會另外收費。

感覺跟以前我在寫 Automation Test Framework 用的 STAF 概念類似,可以作為 Ops as Code 的底層架構。

角色

  • 受控端 (Agent):通常就是 EC2 Instances,也可以是自己 Data Center 裡的機器。
    • 需要安裝 SSM Agent,支援 Windows / Linux
    • 需要設定 IAM Role / Policy
  • 主控端 (Controller):下指令的地方,可以使 AWS EC2 Console 或者透過 AWS CLI / SDK
  • SSM Document: 定義要執行的工作項目,可以想像是 script

SSM Agent

受控的機器要安裝 SSM Agent 之外,要有 IAM Role 可以設定 IAM Policy。

安裝 SSM Agent on EC2 Instances (CentOS, Ubuntu)

根據 region 指定 AWS_DEFAULT_REGION 變數:

1
2
3
4
5
6
7
8
9
# CentOS
curl https://amazon-ssm-${AWS_DEFAULT_REGION}.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm \
-o amazon-ssm-agent.rpm
yum install -y amazon-ssm-agent.rpm

# Ubuntu
curl https://amazon-ssm-${AWS_DEFAULT_REGION}.s3.amazonaws.com/latest/debian_amd64/amazon-ssm-agent.deb \
-o amazon-ssm-agent.deb
dpkg -i amazon-ssm-agent.deb

SSM Agent 執行狀態檢查:

1
2
3
sudo status amazon-ssm-agent
sudo start amazon-ssm-agent
sudo stop amazon-ssm-agent

設定 IAM Policy for EC2 Role

  • 可從 AWS Managed Policies 選擇 AmazonEC2RoleforSSM
  • 設定 Role 的 Trust Relationship
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
    "Service": "ec2.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }

IAM Policy

IAM User

如果你本身就有 Admin 權限,可以跳過這段。

AWS 提供兩個 Policies for Users:

  • AmazonSSMFullAccess: ssm:* 適合給 Admin
  • AmazonSSMReadOnlyAccess: Get*, List*, Describe*`

IAM Role

  • AmazonEC2RoleforSSM

SSM Agent 的 Log

SSM Agent 的執行狀況會寫在 log:

  • /var/log/amazon/ssm/amazon-ssm-agent.log
  • /var/log/amazon/ssm/error.log

內容大概長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
2016-10-19 21:41:47 INFO [instanceID=i-xxxxxxx] [MessageProcessor] increasing error count by 1
2016-10-19 21:41:49 ERROR [instanceID=i-xxxxxxx] [MessageProcessor] error when calling AWS APIs. error details - GetMessages Error: AccessDeniedExc
status code: 400, request id: c910487a-9601-11e6-b114-6719676fc2bc

2016-10-19 22:11:56 INFO [instanceID=i-xxxxxx] [MessageProcessor] SendReply Response{
Description: "Reply a4062b27-66b6-453d-8cf8-1a480f287ac3 was successfully sent.",
MessageId: "aws.ssm.adb1d388-b71d-434b-9471-a1c3f2e1ea23.i-xxxxxxx",
ReplyId: "a4062b27-66b6-453d-8cf8-1a480f287ac3",
ReplyStatus: "QUEUED"
}
2016-10-19 22:15:20 INFO [instanceID=i-xxxxxxx] [HealthCheck] HealthCheck reporting agent health.
2016-10-19 22:20:20 INFO [instanceID=i-xxxxxxx] [HealthCheck] HealthCheck reporting agent health.
  • 這裡可以取得 Agent 是否設定正確的資訊。
  • SSM Agent 每五分鐘會跟 SSM API 溝通,確認 Agent 是可以正常運作的。

Troubleshooting: 確認 SSM Agent 清單

可以透過 AWS CLI 取得現在哪一些機器是受控的:aws ssm describe-instance-information

會產生類似以下的內容,主要是機器名稱、作業系統 (版本)、SSM Agent 版版、是否上線 … 等基本資訊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
aws ssm describe-instance-information
{
"InstanceInformationList": [
{
"IsLatestVersion": true,
"ComputerName": "lab01\n",
"PingStatus": "Online",
"InstanceId": "i-xxxxxxxx",
"IPAddress": "10.50.aaa.xxx",
"ResourceType": "EC2Instance",
"AgentVersion": "1.2.298.0",
"PlatformVersion": "14.04",
"PlatformName": "Ubuntu",
"PlatformType": "Linux",
"LastPingDateTime": 1477371063.958
},
{
"IsLatestVersion": false,
"PingStatus": "Online",
"InstanceId": "i-xxaaaaa",
"ResourceType": "EC2Instance",
"AgentVersion": "3.14.786",
"PlatformVersion": "6.3.9600",
"PlatformName": "Windows Server 2012 R2 Standard",
"PlatformType": "Windows",
"LastPingDateTime": 1477371006.081
},
{
"IsLatestVersion": true,
"ComputerName": "lab02\n",
"PingStatus": "Online",
"InstanceId": "i-dddddd",
"IPAddress": "10.50.xx.qq",
"ResourceType": "EC2Instance",
"AgentVersion": "1.2.298.0",
"PlatformVersion": "2016.03",
"PlatformName": "Amazon Linux AMI",
"PlatformType": "Linux",
"LastPingDateTime": 1477371037.446
}
]
}

也可以個別過濾條件:

1
2
aws ssm describe-instance-information \
--instance-information-filter-list key=InstanceIds,valueSet=i-xxxxxx

如果沒有回覆資料,先確認一下 awscli 的 region 設定是否正確。

執行 Command

執行 Command 可以透過 AWS Console -> EC2 -> Commands -> Command History,或者 AWS CLI,底下的例子是送簡單的 commands:

1
2
3
4
5
6
7
8
9
10
11
aws ssm send-command \
--instance-ids "i-xxxxxxx" \
--document-name "AWS-RunShellScript" \
--parameters commands=ifconfig \
--output text

# 輸出

COMMAND 4ae7d7ea-d80a-4e6c-86f3-662694a543ce AWS-RunShellScript 1477372186.8 1477371586.8 Pending
INSTANCEIDS i-xxxxxxx
COMMANDS ifconfig

取得 Command 執行狀態:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
aws ssm list-command-invocations \
--command-id 4ae7d7ea-d80a-4e6c-86f3-662694a543ce \
--instance-id "i-xxxxxxx"

# 輸出

{
"CommandInvocations": [
{
"InstanceId": "i-xxxxxxx",
"Status": "Success",
"DocumentName": "AWS-RunShellScript",
"CommandId": "4ae7d7ea-d80a-4e6c-86f3-662694a543ce",
"RequestedDateTime": 1477371586.801
}
]
}

安全性

我測試執行 AWS-RunShellScript 這個 Document,跑的 CLI 是 whoamipwdenvdate,結果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
=== Run `whoami`
root
=== Run `pwd`
/
=== Run `env`
TERM=linux
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin
PWD=/
SHLVL=2
UPSTART_INSTANCE=
UPSTART_JOB=amazon-ssm-agent
_=/usr/bin/env
=== Run `date`
Wed Oct 19 22:11:55 CST 2016

發現他就是用 root 在跑,不給 workdir 就會在根目錄,也沒有什麼環境變數。

官方文件也有特別註明,這會有安全性考量,建議最好做適度的管控。

結論

就是設計給 Operator 使用的工具,在 AWS 還沒 Release 前,我就想用類似的工具,像是 STAF / chef 作 Operations 的工作。這個想法成行沒多久,EC2 Run Command 就出來了 XD

雖然概念就是一般的 agent base 應用,像是防毒軟體、權限控管、Chef、CodeDeploy … 但其實還是很實用的。

除了 Operator 使用,也可以串接現在很流行的機器人,做互動控制。

雖然很方便,帶來的就是安全性要特別注意。

延伸閱讀

參考資料


Comments