amazon linux 2022(プレビュー版)でSSM Agentの検証
正式にサポートされてはいないので参考程度です。
GitHub上ではIssueが上がっているようですね。
次回のリリースではパッケージが用意されるっぽいです(そろそろGAに向けたリリース候補が提供予定なので、最後の一歩感ありますね。)
Q: Amazon Linux 2022 (AL2022) の一般提供 (GA) はいつになりますか?
テスト用の AL2022 のリリース候補は、2022 年 7 月末に利用できる予定です。AL2022 GA バージョンは、その数か月後に提供されます。
Amazon Linux 2022のクセのあるところ
SSHのキーとしてRSAキーを使ってはいけないところがハマりどころです。
これはOpen SSHのバージョンが新しいものを利用しているからだそうです。
バージョンを確認してみましょう
$ ssh -V
OpenSSH_8.6p1, OpenSSL 3.0.3 3 May 2022
※今回利用しているAMIは「al2022-ami-2022.0.20220628.8-kernel-5.15-x86_64」です
どうやら今後はRSAキーを利用せずにED25519を利用する形がよさそうですね。
インスタンスプロファイルでSSMへのアクセスを許可
S3やCloudWatchなどへのアクセスはオプションなので、最小限マネージドインスタンスに必要な権限を付与します。
IAMロールを作りましょう。
このときにアタッチするポリシーは「AmazonSSMManagedInstanceCore」です。
IAMロールをEC2に割り当てたらちゃんと反映されているか確認してみましょう。(AWS CLIはプリインストールされているのでそのままawsコマンドが打てます)
$ aws --version
aws-cli/2.7.8 Python/3.9.13 Linux/5.15.43-20.123.amzn2022.x86_64 source/x86_64.amzn.2022 prompt/off
$
$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ****************DQPY iam-role
secret_key ****************Awfl iam-role
region ap-northeast-1 imds
手動でSSM Agentをインストール
今回利用しているAMIは「al2022-ami-2022.0.20220628.8-kernel-5.15-x86_64」ですが、デフォルトでSSM Agentはインストールされていません。正式サポートではないですが、無理やりAmazon Linux 2のrpmからインストールしてみます。
では、インストールしてみましょう。
$ mkdir /tmp/ssm
$ curl https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm -o /tmp/ssm/amazon-ssm-agent.rpm
$ sudo yum install -y /tmp/ssm/amazon-ssm-agent.rpm
Last metadata expiration check: 0:35:03 ago on Sat 16 Jul 2022 01:40:25 PM UTC.
Dependencies resolved.
================================================================================================================
Package Architecture Version Repository Size
================================================================================================================
Installing:
amazon-ssm-agent x86_64 3.1.1575.0-1 @commandline 25 M
Transaction Summary
================================================================================================================
Install 1 Package
Total size: 25 M
Installed size: 94 M
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Running scriptlet: amazon-ssm-agent-3.1.1575.0-1.x86_64 1/1
Preparing : 1/1
Running scriptlet: amazon-ssm-agent-3.1.1575.0-1.x86_64 1/1
Installing : amazon-ssm-agent-3.1.1575.0-1.x86_64 1/1
Running scriptlet: amazon-ssm-agent-3.1.1575.0-1.x86_64 1/1
Created symlink /etc/systemd/system/multi-user.target.wants/amazon-ssm-agent.service → /etc/systemd/system/amazon-ssm-agent.service.
Verifying : amazon-ssm-agent-3.1.1575.0-1.x86_64 1/1
Installed:
amazon-ssm-agent-3.1.1575.0-1.x86_64
Complete!
おまけでステータスを確認してみましょう
$ sudo systemctl status amazon-ssm-agent
● amazon-ssm-agent.service - amazon-ssm-agent
Loaded: loaded (/etc/systemd/system/amazon-ssm-agent.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2022-07-16 14:15:32 UTC; 28min ago
Main PID: 2383 (amazon-ssm-agen)
Tasks: 17 (limit: 1128)
Memory: 17.2M
CPU: 1.010s
CGroup: /system.slice/amazon-ssm-agent.service
tq 2383 /usr/bin/amazon-ssm-agent
mq 2450 /usr/bin/ssm-agent-worker
(以下略)
この状態で利用可能になっています。
コンソールからFleet Managerを見てみるとちゃんと登録されています
【検証内容#1】Systems Manager Inventory
SSM Inventoryはマネージドインスタンスからメタデータを収集して可視化するサービスです。
さっそく有効化してみましょう!
有効化手順
マネジメントコンソールにログインしてSystems Managerのページを表示します。
左ペインから「インベントリ」をクリックします。
「すべてのインスタンスでインベントリを有効にするには、ここをクリックします。」をクリック
裏側では以下のAWSが所有しているSystems Manager Automationのドキュメントが有効化されています。※状況はステートマネージャーから確認できます。
ドキュメント名:AWS-GatherSoftwareInventory
Fleet Managerの画面から確認
各インスタンスのインベントリの情報はFleet Managerから確認可能です。
【検証内容#2】Systems Manager Automation(下準備)
今回はSSM Automationを使ってインスタンスの自動起動のジョブを組んでみようと思います。
シンプルにPostgreSQLをインストールしてDBを起動するところまでをやってみようと思います。
※例によってAmazon Linux 2022自体はちゃんと動作保証がされていないので動かなかったどんまいということで…
yumで探してみると13系が利用できそうなので、それでもいいかなと思いつつ、そしたらsystemctlで自動起動すればいいんじゃないかなとなりそうなので、あえてソースコードからインストールして最新の14.4を動かしてみようかなと思います。
以下のコマンドを実行してインストールしていきます。
# 必要なパッケージをインストール
sudo yum install -y readline-devel
sudo yum install -y zlib-devel
sudo yum install -y openssl-devel
# インストールユーザの作成(postgres)
sudo useradd postgres
sudo passwd postgres
# インストール先(ドキュメントのデフォルトのもの)
sudo mkdir /usr/local/pgsql
sudo chown postgres. /usr/local/pgsql
# ソールコードの配置
cd /usr/local/src; pwd
sudo curl https://ftp.postgresql.org/pub/source/v14.4/postgresql-14.4.tar.gz --output postgresql-14.4.tar.gz
# 解凍
sudo gunzip postgresql-14.4.tar.gz
sudo tar xf postgresql-14.4.tar
sudo chown -R postgres. postgresql-14.4
# インストール
sudo su - postgres
cd /usr/local/src/postgresql-14.4/;pwd
./configure --with-openssl
make world
make check
make install-world
make install-docs
make clean
# 環境変数の設定
cp -pv ~/.bash_profile ~/.bash_profile_bk
cat << 'EOF' >> ~/.bash_profile
export PGHOME=/usr/local/pgsql
export PATH=$PGHOME/bin:$PATH
export MANPATH=/usr/local/pgsql/share/man:$MANPATH
export PGDATA=/usr/local/pgsql/data
EOF
exit
sudo su - postgres
# データ用のディレクトリ作成
mkdir /usr/local
initdb --encoding=UTF8 --no-local
pg_ctl -l logfile start
psql -l
pg_ctl stop
インストールが完了したら、EC2インスタンスを停止しておきます。
そしたらAutomationのドキュメントを作っていきましょう。
【検証内容#2】Systems Manager Automation
Systems ManagerのAutomationで以下のフローを書いてみます。
- 「EC2インスタンスの起動」はAWS側のAPIをコール⇒pythonの関数※
- 「PostgreSQLサーバのプロセスを起動」はEC2内のコマンドをコール⇒Bash
※よくやる操作はアクションタイプからテンプレートが提供されていたりします。EC2を起動する操作もテンプレートが提供されています。ただし、インスタンスIDを入力する必要があり柔軟性がないので、今回はTagの中のNameで対象のインスタンスを抽出するロジックを書きたいのでPythonのコードを利用します。
マネジメントコンソールからSSMドキュメントの画面を表示します。
「Create document」から「Automation」を選択します。
ここからはビルダー画面でそれぞれの設定を整理していきます。
ドキュメント詳細
名前を入れるだけです。
ドキュメント属性
IAMロールを事前に作っておいて、SSM AutomationがそれをAssumeRoleするようにします。これはexecuteScriptやRunCommandを実施するための権限を付与しておきます。
今回はざっくり以下のマネージドポリシーをアタッチしたロールで動作確認しています。
- AmazonEC2FullAccess
- AmazonSSMAutomationRole
ステップ1 EC2インスタンスの起動
設定項目1 | 設定項目2 | 設定値 |
---|---|---|
ステップ名 | - | StartEC2Instance |
アクションタイプ | - | aws:executeScript |
入力 | Runtime | python3.6 |
Handler | script_handler | |
Script | 表の下に記載 | |
出力 | 名前 | TargetInstanceIds |
セレクター | $.Payload | |
タイプ | StringMap |
def script_handler(events, context):
import boto3
tagKey = 'Name'
tagValue = 'ssm-test-003'
#Initialize client
ec2 = boto3.client('ec2')
instanceQuery = ec2.describe_instances(
Filters=[
{
"Name": "tag:" + tagKey,
"Values": [tagValue]
}]
)
if not instanceQuery['Reservations']:
noInstancesForTagString = "No instances found for specified tag."
return({ 'noInstancesFound' : noInstancesForTagString })
else:
queryResponse = instanceQuery['Reservations']
for results in queryResponse:
instanceSet = results['Instances']
instanceIds = []
for instance in instanceSet:
if instance['State']['Name'] == 'stopped':
instanceIds.append(instance['InstanceId'])
if not instanceIds:
message_body = "no instance is stopped"
else:
ec2.start_instances(InstanceIds = instanceIds)
message_body = "start instaces"
return ({"instance_ids": instanceIds})
ステップ2 EC2のステータスがOKになるまで待機する
設定項目1 | 設定項目2 | 設定値 |
---|---|---|
ステップ名 | - | WaitEC2StatusOK |
アクションタイプ | - | aws:executeScript |
入力 | Runtime | python3.6 |
Handler | poll_instance | |
Script | 表の下に記載 | |
追加の入力 | 入力名 | InputPayload |
入力値 | {{ StartEC2Instance.TargetInstanceIds }} |
def poll_instance(events, context):
import boto3
import time
ec2 = boto3.client('ec2')
instance_ids = events['instance_ids']
instance_status = "null"
for instance_id in instance_ids:
while True:
res = ec2.describe_instance_status(InstanceIds=[instance_id])
if len(res['InstanceStatuses']) == 0:
print("Instance status information is not available yet")
time.sleep(5)
continue
instance_status = res['InstanceStatuses'][0]['InstanceStatus']['Status']
print('[INFO] Polling to get status of the instance', instance_status)
if instance_status == 'ok':
break
time.sleep(10)
time.sleep(60)
return {'Status': instance_status, 'InstanceId': instance_ids}
ステップ2 マネージドインスタンス上で起動コマンドを実行
設定項目1 | 設定項目2 | 設定値 |
---|---|---|
ステップ名 | - | StartPostgreSQL |
アクションタイプ | - | aws:runCommand |
入力 | Document name | AWS-RunShellScript |
Targets | [{"Key":"tag:Name","Values": ["ssm-test-003"]}] | |
追加の入力 | 入力名 | Parameters |
入力値 | {"commands":["#!/bin/bash", "sudo su - postgres -c 'pg_ctl -l logfile start'"]} | |
実行してみる
ドキュメントの詳細ページから「オートメーションを実行」をクリック
シンプルな実行のまま何もいじらず、実行をクリック
正常に実行完了したら、Fleet Managerからターミナルセッションを起動してちゃんと実行されているか確認する
【おまけ】SSM AgentつながりでInspectorを見てみた
マネージドインスタンスとして認識されていても、Inspectorのコンソールから見てみたらサポートされていないOSとしてスキャンの対象外になっていました。
そりゃそうか…