Ansible Towre + GitLab + moleculeで作るCI/CD環境


AnsibleのPlaybookやRoleのCI/CDをAnsible Tower + GitLab + moleculeを使って出来ないか検証してみたので書いてみようと思います。

やること

ここでは、Apacheの設定やコンテンツを自動的にテストしてプロダクション環境への反映までやってみます。
流れは以下の通りです。

User

ユーザーは、PlaybookやRoleおよびApacheの設定とコンテンツを作成します。
普通、コンテンツはCMSで管理するとは思いますが、ここでは挙動確認のため簡単なコンテンツを作成してプロダクション環境へ反映します。

GitLab

GitLabでは、リポジトリの管理とCIおよびAnsible TowerのWF実行までを実施します。
ユーザーは、作成したPlaybookなどをリポジトリに反映すると自動で以下のテストが実施されます。

  • main playbook lintテスト
    • roleを呼び出すPlaybookのyamllint
    • roleを呼び出すPlaybookのansible-lint
  • moleculeでroleのテスト
    • yamllint
    • ansible-lint
    • dockerコンテナをデプロイ
      • コンテナ内でroleを実行
      • role実行後にWeb接続のテスト
    • dockerコンテナを削除

最後にテストで問題が無い場合はAnsible TowerのWorkFlow(WF)を実行します。
※本番ではmasterへ直接pushなんとことはしないと思いますが、今回は検証なので直接pushします

うれしいこと

これをやって嬉しい(メリット)と感じることは以下の通りです。

  • いつ だれが どのファイルに対して どういった変更を加えたか が自動で記録されます
  • マージリクエストを使うことで 背景や理由 目的 切り戻し用のcommit なども書いて記録できます
  • テキストファイル(変数ファイルやraw設定ファイルなど)で構成を管理できます
  • テストが自動で実行され記録も自動で残ります
    • この記録があると無いとじゃ本番への適応の心理的負担が減ると感じています
    • また、記録が残ることで振り返りや情報共有もやりやすくなります
    • 自動化出来るものは人が記録を残すよりシステム側で機械的にやった方が情報は詳細に残りやすいと思います。

Ansible Tower

Ansible Towerでは、プロダクションサーバにPlaybookを実行します。
WFで定義しておいた以下のフローが実行されます。

  • Apacheのインストール
  • Apacheの設定とコンテンツのアップデート
    • アップデート処理が走った場合は最後にApacheの再起動(graceful or restart)
  • (理想は)もし、新しい設定をプロダクションサーバ適応後にエラーが発生した場合は自動切り戻し
    • ここでは、簡単な検証しかしないため実装していないですが、本番では自動切り戻しを意識して実装しておくのが良いと思います。

うれしいこと

これをやって嬉しい(メリット)と感じることは以下の通りです。

  • いつ だれが なんのサーバに対して処理をしたか が自動で記録されます
  • セキュリティーやロールによるアクセス制御などのガバナンスの強化ができます
  • Ansible Towerの詳細な実行記録をログ解析ツール(例えばElasticsearch + Kibana、Splunkなど)へ取り込むことによってログを自在に可視化することができます
  • Ansible Towerであれば何かあったらサポートに助けてもらえます

まだ、Ansible Towerでは実装されていませんが、AWX(Ansible Towerのアップストリーム版)で実装された承認機能と連携すれば自動でWFは実行されるが本番適応は別担当者が承認するという運用も可能です。
詳しくは以下を参照ください。

検証環境

検証環境は以下のようになっています。

バージョン

項目 OS バージョン 備考
Client CentOS 7.5 playbook作成する端末
Ansible Tower RHEL 7.6 3.5.1
GitLab CentOS 7.7 ce-12.2.5-ce.0
GitLabRunner CentOS 7.7 12.3.0-1
webserver CentOS 7.6 Web設定を適応するサーバ

検証環境設定

GitLab

パイプラインの最後にdeployを実行します。
deployでは tower-cli を使ってAnsible TowerのWFを実行します。
WFを実行するにはユーザーとパスワードが必要です。
そのため、パスワードはGitLabのCI/CD Variableに登録してマスクします。

プロジェクトの Settings -> CI/CD -> Variables へ移動して変数を登録します。
ここでは ansible_tower_passwd という変数名で登録しました。

GitLabRunner

GitLab Runnerの設定は以下の通りです。

executorを shell にしている理由については以下を参照ください。

後、dockerのコンテナ操作をするのでgitlab-runnerユーザーには以下のsudo設定をしています。

sudoを実行してもPATH環境変数を維持するのとNOPASSWDで実行できるようにしています。
後、必要なモジュールは以下の通りインストールしています。

tower-cliで証明書検証を無効かしています。

また、CentOS7の標準gitでは以下の不具合が発生します。

そのため、GitLabRunnerではgitをソースからインストールしています。

gitインストール後、ソースでインストールしたgitにパスを通します。

Ansible Tower

プロジェクトの設定です。

テンプレートの設定です。

ワークフローの設定です。

ワークフローは以下のようになっています。

ワークフローでは同じテンプレートを使っています。
テンプレートの流れは apache install -> apache config and web contents update の順で実行されます。
処理の中では以下のようにタグで実行を分けています。

最初の処理(apache install)のタグです。

次の処理(apache config and web contents update)のタグです。

WFには切り戻し用のテンプレートもあるように見えますが、今回は実装していないのでイメージです。
Playbook、Roleの実装についてはこの後に説明します。

Playbook/Role仕様

今回作成したものは以下にアップしました。
具体的なコードについては以下を参照してください。

階層仕様

今回は以下のように作成しました。

PlaybookとRoleについて

今回はタグのand条件で実行したい処理を分けるようにしています。
例えば、以下はmain.ymlの実装です。

apache タグが指定された場合はapacheのroleが実行されるようにしています。
roleのtasksでは install config_update delete が定義されています。

例えば apache,install というタグを指定した場合はapache roleのinstall処理だけが実行されます。
また apache,config_update というタグを指定した場合はapache roleのconfig_update処理だけが実行されます。
これで、目的に合ったタグを指定することでやりたい処理のみを実行するようにしています。
これはroleで処理をひとまとめに管理したい場合やAnsible Towerで一つのテンプレートでいくつかの処理を分けたい場合に役立つと思っています。

moleculeのテストについて

工夫した点

moleculeのテストでテストインスタンス内でroleを実行した後のWeb接続確認テストをどうしようかと思っていたのですが、moleculeではroleを実行した後に side_effect と言うタスクが実行されます。

今回はroleを実行した後のWeb接続確認用Playbookを side_effect で実行しています。
side_effectの実装は以下のようになっています。

テストインスタンスのIP情報を元にuriモジュールで接続して、ステータスコードが200か、取得したコンテンツ内に指定した文字が存在しているか、をassertで確認しています。
例えば、VirtualHostを増やした場合は、このテストを増やすイメージです。

デモ動画

以下はapacheのインストールからwww.example1.comのVirtualHostのテスト・webserverへ反映するまでのデモ動画です。

Ansible CICD demo (apache version) from sky_joker on Vimeo.

以下はVirtualHost(www.example2.com)を追加した時のデモ動画です。

Ansible CICD demo (example add virtualhost to apache) from sky_joker on Vimeo.

こんなイメージで運用が出来るのではないかと思っています。

最後に

Ansible Tower + GitLab + moleculeを組み合わせてCI/CDが出来ることが確認できました 🙂
moleculeでは、roleテストを実行する前にprepareに事前環境を定義することも可能です。
また、delegatedドライバを使うことで標準ドライバが存在しない場合やそれ以上のことをやりたい時に柔軟に対応できます。

基本的にAnsibleの処理はroleで書いてroleごとのテストをmoleculeでやってデプロイをAnsible TowerやAWXを使う感じが今のところいいのかなと個人的に思っています。
後、直デプロイではなくDry RunまでをAnsible Tower側で自動実行しておいて、プロダクション環境への反映は人がAnsible Towerのボタンを押すと言うのもいいと思います。
インフラ自動化も奥が深くて楽しいです 🙂

それでは、みんなでハッピーオートメーション!

Leave a Reply

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください