テクノロジの無駄づかい

日々の「ステュディオス」を求めて遠回りしがちなエンジニアの記録

AWS Systems Manager を触ってみた

AWS Systems Manager (SSM)はAWS上、オンプレミスに関係なくSSMエージェントが稼働するサーバインスタンスを一元管理するためのサービス。

存在は知っていて、パラメータストアのような一部の機能は使っていたものの、AWSコンソールからオンプレサーバを操作するっていうのがどこまでできるのか気になっていた。でやってみた。

このエントリは次の3日目の記事となる。

qiita.com

マネージドインスタンスの登録

本エントリではAWSの外、つまり、AWS以外のデータセンターや自宅などで稼働するサーバを物理、仮想を問わずオンプレサーバと呼ぶことにする。

SSMより管理されるサーバはマネージドインスタンスと呼ばれる。 マネージドインスタンスには SSMエージェントをインストールする必要がある。

  1. アクティベーションの作成
  2. SSMエージェントのインストール(その手順の中でアクティベーション

順にやってみた。

アクティベーションの作成

最初にAWSのSSMコンソールでアクティベーションを作成する。 ここでいう「アクティベーションを作成する」とは、SSMエージェントをアクティベーションする際の「アクティベーションコードを発行する」ことである。

以下に手順を示す。

  1. AWS Systems Mangerのコンソールのアイティベーションにアクセスする。
    f:id:HeRo:20181202095034p:plain
    SSM - アクティベーション
  2. 右上の「アクティベーションの作成」をクリックする。
  3. 必要な項目を入力しアクティベーションを作成する

    f:id:HeRo:20181202095148p:plain
    SSM − アクティベーションの作成

    • デフォルト値のまま登録しても良い。
    • IAMロールは「システムの作成したデフォルトコマンド実行ロール」を選択すると、初回実行時にAmazonEC2RunCommandRoleForManagedInstancesが作成される。
    • デフォルト値のままだとインスタンス制限1となっているのでアクティベーションできるインスタンスが1つだけとなってしまう。複数のインスタンスを登録するときにはインスタンス制限の数を設定する。
    • 実運用の際にはアクティベーションの有効期限を設定したほうが良いと思われる。
  4. 登録後表示される Activation CodeActivation IDを控えておく。これがエージェントのインストールの際に必要となる。
    • 再び参照できないのでなくさないようにする必要がある。
    • なくしたらまたアクティベーションを作成すれば良いだけだが、面倒。

SSMエージェントのインストール

SSMエージェントは次のOSにインストールできる。

各OSへのインストールは次の資料の手順が示されている。

このエントリではUbuntu 18.04 Serverで試してみた。 Ubuntuの場合のインストール手順は次の通り。

mkdir /tmp/ssm
curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb -o /tmp/ssm/amazon-ssm-agent.deb
sudo dpkg -i /tmp/ssm/amazon-ssm-agent.deb
sudo service amazon-ssm-agent stop
sudo amazon-ssm-agent -register -code "activation-code" -id "activation-id" -region "region"
sudo service amazon-ssm-agent start

この5行目でSSMエージェントのアクティベーションを行っている。 その際に先に作成したアクティベーションActivation CodeActivation IDを利用する。

試したところ全くつまずくところはなく、すんなりインストールできる。 設定に成功するとしばらくして次の様にAWSコンソールでマネージドインスタンスとして表示される。

f:id:HeRo:20181202101449p:plain
SSM - マネージドインスタンス
マネージドインスタンスになれば、AWSコンソールからの操作を行うことができる。

シェルコマンドの実行

SSMエージェントを通して任意のシェルコマンドを実行できる。
ハローワールド代わりに、次のコマンドを実行してみた。

date
ls -l /etc/

マネージドインスタンス上でコマンドを実行するには[アクション]-[ランコマンド]を利用する。 以下に手順を示す。

コマンドのドキュメント

実行できるコマンドは[共有リソース]-[ドキュメント]で定義され、管理されているようだ。
任意のシェルコマンドを実行させるには AWS-RunShellScript ドキュメントを利用する。

ということで、最初に次の様にAWS-RunShellScriptを選択する。

f:id:HeRo:20181202101900p:plain
SSM ランコマンド ドキュメントの選択

コマンドのパラメータ

続いてコマンドのパラメータを設定する。 ここは、選択したコマンドにより異なるが、AWS-RunShellScriptの場合、次のようなUIになっており、実行するシェルコマンドを直接記述する。

f:id:HeRo:20181202102325p:plain
SSM ランコマンド コマンドのパラメータ

ターゲット

次に実行対象のマネージドインスタンスを選択する。

f:id:HeRo:20181202102919p:plain
SSM ランコマンド ターゲットの指定

直接指定することもできるが、マネージドインスタンスに設定したタグで指定すれば、複数インスタンスを一度に設定できるのであろう。

その他の設定

他に次の設定を行うことができる。詳細は省略。

  • コメント
  • 実行レートの制御
  • 出力オプション 次の出力先を指定できる。択一でなく複数出力も可能
  • SNS通知

最後にはコンソールからではなくCLIで実行する場合のオプション設定済みのCLIコマンドも表示される。

実行

実行すると次の様に実行ステータスが表示される。

![SSM ランコマンド 実行状況

f:id:HeRo:20181202112225p:plain
SSM ランコマンド 実行状況

全体の進行状況が表示されるとともに、個々のターゲットでの実行時の出力も確認できる。

結果の出力

コマンドの実行結果を確認する。 AWSコンソールのSSMランコマンドのコマンド履歴で確認することができる。

また、出力先にS3を指定しているとコマンドの標準出力がファイルに出力される。 この例の場合、次の内容のファイルが指定バケットの指定ディレクトリに出力される。

2018年 12月 02日日曜日 16:15:24 JST
合計 796
drwxr-xr-x 4 root root    4096 11月 29  2017 X11
-rw-r--r-- 1 root root    2981 11月 29  2017 adduser.conf
drwxr-xr-x 2 root root    4096 11月  5 20:53 alternatives
〜 以下略 〜

期待通りの結果が出力されている。

Dockerコンテナの起動

さて、個々のコマンドを実行してできることを確認するよりもDockerコンテナを起動できれば、各サーバのソフトウェア環境にかかわらず処理を実行させることができるであろうと考えて試してみた。

EC2インスタンスではなく物理マシン上の Ubuntu 18.04 LTS server にSSMエージェントをインストールして、Dockerコンテナを起動するまでを試みた。

Docker は apt でインストールする

SSMエージェントを通して次のコマンドを実行してみる。

echo $PATH

すると出力結果は次の通り。これがSSMエージェントに通っているPATHということになる。

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

一方、Ubuntu 18.04 LTS serverでは最近追加されたsnapの利用を促される。 Dockerもsnapでインストールするよう促されるが、それに従うと/snap/bin/dockerにインストールされてしまう。が、SSMエージェントのパスに/snap/binが追加されるわけでもなくDockerコマンドが見なからないという結果になった。

aptでのインストールもできるので、そちらでインストールすると パスの通ったところにDockerがインストールされるのでsnapではなくaptでインストールする必要がある。

Dockerコンテナの起動にはAWS-RunShellScriptを使う

SSMにはAWS-RunDockerActionドキュメントというその用途用のドキュメントが存在する。しかしそれを利用した場合、次の様にイメージのpullには成功しているようだが、コンテナの起動には失敗してしまった。

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f17d81b4b692: Pulling fs layer
82dca86e04c3: Pulling fs layer
046ccb106982: Pulling fs layer
046ccb106982: Verifying Checksum
046ccb106982: Download complete
f17d81b4b692: Download complete
82dca86e04c3: Verifying Checksum
82dca86e04c3: Download complete
f17d81b4b692: Pull complete
82dca86e04c3: Pull complete
046ccb106982: Pull complete
Digest: sha256:d59a1aa7866258751a261bae525a1842c7ff0662d4f34a355d5f36826abc0341
Status: Downloaded newer image for nginx:latest
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"\": executable file not found in $PATH": unknown.
failed to run commands: exit status 127

一方、汎用のシェルコマンド実行用のAWS-RunShellScriptドキュメントを利用して次を実行するとDockerコンテナの起動に成功した。

項目 設定値
コマンドのドキュメント AWS-RunShellScript
commands docker run --name some-nginx -d -p 8080:80 nginx

これは Nginxを起動するものだが、別マシンからのnginxへのアクセスも可能であった。

AppArmer

もう一つ問題があった。

Ubuntu18.04ではAppArmerが有効になっている。
そのため、起動したコンテナを止められない事象が発生した。

次のコマンドでAppArmerをとめるとコンテナを停止できる。

sudo aa-status # 状態の確認
systemctl disable apparmor.service --now
service apparmor teardown

上記の実行後、次の設定で起動したDockerコンテナを停止できた。

項目 設定値
コマンドのドキュメント AWS-RunShellScript
commands docker stop some-nginx

実運用の際にはAppArmerを止めるか、適切な設定が必要になるだろう。

まとめ

  • SSMエージェントをUbuntuにインストールして、SSMコンソールから操作できることを確認した。
  • 任意のコマンドの実行が可能で、Dockerコンテナの起動も可能。
  • しかし、AppArmerによる制限があるので注意が必要。

また、主にはUbuntu で試したのだけど、SSMエージェントはRaspbianにもインストール可能となっている。任意のシェルコマンド実行までは動作することを確認した。Dockerコンテナ起動については未実施。

参考