S3 に置いた Playbook を基に Fargate のタスクとして Ansible を実行する

はじめに

この記事は Ansible Advent Calendar 2018 19 日目、12/19(水)の記事です。
すみません、すでに日付が変わって遅刻してしまいました。
去年のアドベントカレンダーは 20 日目担当で、その際にブログを作ったので 1 周年です。
全然書けてないのでもっと書かないとですね。

Docker Image を準備する

Fargate を使うためには Docker Image をどこぞのリポジトリに作成しておく必要があります。
今回はスタンダードに Docker Hub を使用しています。今度は ECR で試したい。

以下のような Dockerfile を用意しました。
Fargate は毎回 docker pull でイメージを取ってくるので、alpine ベースで作成しています。
一応 ansible-playbook コマンドが実行できるようにはなっていますが、実際に使うと足りないものが出てくるかもしれません。
※まだ検証ができておりません。。。
ちなみに CentOS ベースに yum で入れるとそこそこの容量になってタスク実行までが遅くなってしまいました。

FROM alpine

# run commands for install ansible
RUN apk add --no-cache python2 curl gcc make libffi-dev python2-dev musl-dev openssl-dev && \
    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
    python get-pip.py && \
    rm -f get-pip.py && \
    pip install ansible awscli && \
    apk del --purge gcc make && \
    rm -rf /root/.cache/pip && \
    adduser -D ansible

USER ansible
WORKDIR /home/ansible

# copy files
COPY ./file/ansible.cfg /etc/ansible/ansible.cfg
COPY --chown=ansible:ansible ./file/entry.sh /home/ansible/entry.sh

ENTRYPOINT ["/bin/sh", "/home/ansible/entry.sh"]

ENTRYPOINT として指定しているスクリプトは以下の通りです。
第一引数で playbook が置いてある S3 パスを指定し、その後の引数は実行したいコマンドをそのまま書くようにしてみました。

#!/bin/sh
aws s3 cp s3://$1/ /home/ansible --recursive
shift 1
exec $*
exit 0

この Dockerfile を用いてビルドしたイメージは g40244/fargate-ansible にてご利用頂けます。

ECS で実行環境を作る

イメージが作成できたら、AWS 側で ECS をセットアップします。

クラスター作成

まずは ECS のクラスターを作成します。
Fargate を使用するため、クラスターテンプレートは「ネットワーキングのみ」を選択します。
f:id:g40244:20181220020058p:plain

クラスターの設定では、名前と VPC を設定します。
すでに ECS 用の VPC がある場合は選択せずに作成します。
試すだけであれば、ここで VPC を作成して利用するのが楽です。
f:id:g40244:20181220020107p:plain

タスク定義の作成

クラスターが作成できたら、次はタスク定義を作成します。
タスク定義では主に、以下の内容を定義します。
* コンテナに与える権限⇒タスクロール
* コンテナに与えるリソース⇒タスクサイズ
* どのコンテナをどのように動かす⇒コンテナの定義

起動タイプの互換性は、もちろん Fargate を選択します。
f:id:g40244:20181220021643p:plain

playbook をコンテナ内にコピーできるよう、タスクロールには S3 へのアクセス権限を付与しておきます。
コンテナが AWS リソースにアクセスできるようにしたい場合は、ここで定義するロールに権限を割り当てます。
f:id:g40244:20181220021738p:plain

タスク実行ロールは自動で作成されるもので問題ありません。
タスクサイズについては Ansible に実行させる playbook 次第で設定する必要がありそうです。
f:id:g40244:20181220021959p:plain

コンテナの定義では、先ほど作成した Docker Image のパスを記載します。
f:id:g40244:20181220022102p:plain

また、ここでエントリポイントとコマンドを上書きすることができます。
イメージの作り上、コマンドのみを変更します。ここで playbook 配置先の S3 パスと、実行コマンドを定義します。
f:id:g40244:20181220022315p:plain

定義したタスクを実行する

タスク定義が作成できたら、いよいよタスク実行です。
作成したタスク定義を選択し、「アクション」から「タスクの実行」を選択します。
f:id:g40244:20181220022845p:plain

タスク実行の際も少し設定が必要となります。
ここでは使用するタスク定義、実行するクラスター、タスクの数、実行する VPC とセキュリティグループを選択します。
VPC とサブネットは S3 アクセスのため、パブリックのものを選択しました。
セキュリティグループは変更しないとタスク実行のたびに作成されてしまいますので、なるべく既存のものを選択します。
タスクのタグ付けは無効にしておかないと失敗してしまいました。
f:id:g40244:20181220023334p:plain f:id:g40244:20181220023352p:plain f:id:g40244:20181220024122p:plain

問題なければ正常にタスクが開始されます。
ステータスはPROVISIONING⇒RUNNING⇒STOPPEDと遷移していきます。
※一部省略
f:id:g40244:20181220024219p:plain f:id:g40244:20181220024845p:plain f:id:g40244:20181220024903p:plain f:id:g40244:20181220024919p:plain

ログを確認すると、playbook がダウンロードされ、実行されていることが分かります。
今回は playbook や inventory をちゃんと作っていないため、unreachable となっています。
f:id:g40244:20181220025111p:plain

おわりに

Fargate を使って、S3 から playbook をダウンロードしてきて実行することができました。
VPC 上で実行できるため、VPN や Direct Connect を活用することで
AWS 上のリソースだけでなく、オンプレのリソースも対象とすることができます。

現在、Code シリーズを使って playbook を git push したらこのタスクを使って Ansible デプロイ検証中です。
成功すれば別記事にして、リンクを貼ろうと思います。
これ Ansible より Fargate がメインの記事になっちゃったな

実行環境はサクッと用意して、ひたすら playbook を書いて Enjoy Ansible !!