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 10
| # 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
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 是 whoami、pwd、env、date,結果如下:
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 使用,也可以串接現在很流行的機器人,做互動控制。
雖然很方便,帶來的就是安全性要特別注意。
延伸閱讀
參考資料