Ignite の中身: Ansible Playbook を Systems Manager から実行して cloud-init の重荷をへらす

はじめに

今週のエントリーでは、AWS Systems ManagerAnsible についてのお話を。

Ignite ではアプリケーション開発を行うサンプルを各種公開しています。

アプリ開発にはメトリックの取得が不可欠、ということでアプリケーションのメトリックを取得・整形・表示するシステムが必要になります。 プロダクトオーナーさんには既存のアプリケーションが充分な速度を出しているか(例: 90パーセンタイル)を知る手段になりますし、アプリ開発チームには新しいコードがどれだけ速度アップをしたか(あるいは速度ダウンをしていないか)を計測する手立てになります。

ここでは、メトリックの取得・整形・表示システムとして、Prometheus, Alertmanager, Grafana をアプリケーションと共に構築するようにしました。

これをいかに効率よく構築するかを考えた結果、Ansible の AWS ならではの使い方、ついでに運用も楽できる方法がありましたのでご紹介いたします。

はじめの設定 - cloud-init で 設定

Ignite のあるサンプルでは、以下のようなアプリ(右 AutoScaling 部分)と、メトリック取得(左の ec2) が自動で構築されます。

devsecimage

自動でインストールするために、下記のような bash スクリプトを cloud-init から走らせていました。

# install prometheus
echo "=== installing prometheus ==="
sudo useradd --no-create-home --shell /bin/false prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo mkdir /var/lib/prometheus
cd /tmp; wget https://github.com/prometheus/prometheus/releases/download/v2.0.0/prometheus-2.0.0.linux-amd64.tar.gz
tar zxf prometheus-2.0.0.linux-amd64.tar.gz
mv prometheus-2.0.0.linux-amd64 /opt/prometheus && rm -f /tmp/prometheus-2.0.0.linux-amd64.tar.gz
sudo chown -R prometheus:prometheus /opt/prometheus /var/lib/prometheus

    (snip このあと90行ほど)

単純・線形・直列な設定なら良いのですが、複雑な設定が必要になるとすぐに破綻します。 そのようなときは、設定用途に特化した CMS (構成管理ツール)を利用するのが一番です。

特に、CMS の中で最もとっつきやすく各種モジュールが用意されている Ansible がオススメです。


自分が思っていた Ansible for EC2

じつは、AWS EC2 で Ansible を使う場合、以下のような構成が必要で面倒だと思っていました。

  • Ansible Workstation (ノートPC、または、ec2)
  • インストール先 ec2 に SSH 公開鍵追加
    • Ansible Workstation には SSH 秘密鍵を用意
  • インストール先 ec2 / Ansible Workstation 間のネットワーク
    • public network + public IP
    • bastion ホスト

bastion ansible

AWS を使うことでせっかく、権限や認証を IAM に一本化でき、ネットワーク公開も必要最小限に抑えたというのに台無しに・・というのは間違いでした!


本当は楽な Ansible for EC2 (+SSM)

じつは、AWS Systems Manager (SSM) のランコマンドを使えば、IAM を認証として使いつつ、ネットワーク公開も最小限に抑えることが可能です。

本サンプルでは、CodePipeline から Lambda を実行、 Lambda 関数からターゲット ec2 にSSM 経由で ansible-playbook を実行しています。

以下に、この構成のポイントをご紹介します。

  • SSM 用ロール arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM を Prometheus 用インスタンスプロファイルにアタッチしておく
  • インストール先 ec2 に ssm-agent と ansible をインストールしておく
  • インストール先 ec2 にタグを付与しておく
  • ansible plybook を作っておく

playbook dir構成

ここで、site.ymlファイルは以下のように設定し、各 role を実行するようにします。

  ---
  - hosts: targets
    roles:
      - prometheus
      - alertmanager
      - grafana

さらに、inventoryファイルで target に localhost を指定。

  [targets]
  localhost ansible_connection=local

このファイルは、CodePipeline のタスクへ InputArtifacts として渡すようにしておきます。

最後に、SSM の AWS-RunRemoteScript を利用してコマンドを実行します

cd playbooks; ansible-playbook -i inventory -e 'SlackUrl=${SlackUrl} SlackChannel=${SlackChannel} grafana_admin_user=${GrafanaUsername4Staging} grafana_admin_pass=${GrafanaPassword4Staging}' site.yml

こうすることで、もともと自分が思っていた SSH 公開鍵設定やネットワーク設定も必要なく、AWS のリソース設定だけで Ansible によるインストールができました。


まとめ

SSM ランコマンドを使用することで、管理オーバーヘッドを抑えつつ(SSH鍵、basionホスト不要)、セキュアに一括運用ができるところを見ていただけたと思います。

CloudFormationなどで構築・設定を自動化し、SSMで運用を自動化すると、マニュアル作業の自動化を徹底的に行えるようになります。

なお、今回は Linux 向けの汎用的なプラグインを使いましたが、他にもWindows Server 向けの AWS-RunPowerShellScript などプラグインが多数用意されています。 それぞれのユースケースにしたがってピックアップしてみてください。

試したいときは・・

今回の SSM RunCommand は、Ignite に用意された devsecops サンプルから試すことができます。

Ignite dashboardへ

運用の自動化だけでなく、セキュリティを確保した CI/CD パイプラインが構築されますので、そちらも試してみてください。

results matching ""

    No results matching ""