Playbookを秘伝のタレ化しないために考えていること
お久しぶりです、村です。
最近、自分や他人が作成したPlaybookを運用する機会が増えてきました。 そこで、Playbookを作成する際、運用目線的にはどうすれば良いのか、ぼんやり考えていることを書こうと思います。
問題
他人が書いたPlaybook(およびその周辺環境)を見ていて困ったことはこの辺です。
- 実行手順がわからない
- 渡す引数は何が必須?
- サーバ全台に無邪気に適用していいんだっけ
- 改修やリファクタが結構しんどい
- なんかイケてないから直したいけど、影響箇所が多すぎて直せない
- これ何でこんな書き方してるんだ?
...最終的に誰も手をつけたくなくなっていることがあります。
PlaybookはYAMLだし、コードほど行数やファイル数が膨らむこともそうないので根気強く読める人がいればいいのですが、 担当者が離任したりして秘伝のタレ化...みたいな事態は珍しくない気がします。
ゴール
- 作成したPlaybookが長く運用できること
- Playbookが属人化しないこと (そもそもPlaybookは長く使うものじゃないというツッコミはこの際無視します・・・笑)
対象読者
- Playbookを書いている人
- Playbookを運用している人
解決策?
当たり前のことが多いですが、この辺をすることで少しはよくなる気がします。 思いつき次第追記していこうと思います。(結構漏れている気がするので...)
Playbookの情報を記述しよう
- どの環境で、どういう手順で実行できるかを残しましょう。
- 誰にでも実行できるわけではないPlaybookは属人化しやすいです。
- リポジトリのREADMEとかに残すのもいいと思います。
↓こんな感じ
# README ## 概要 Webサーバ新規構築用Playbookです。 ## 変数 - var1: (説明1) - var2: (説明2) - var3: (説明3)
シンプルさ・読みやすさを保とう
- 読みにくいものは秘伝のタレ化しやすいうえ、改修しにくいです。
- 例えばjinja2テンプレート以下でfor文を回す、みたいな記述はできるだけやめましょう。。。
- Ansibleの機能をうまく使用してシンプルに・わかりやすく書きましょう。
- 前のバージョンのドキュメントですが、おすすめです。
手作業の手順書を残そう
- Ansible実行環境が障害に陥った際、最後に頼るのは手作業であるから、です。
- いつでも実行環境があり、必ずジョブが成功すれば良いのですが、そういうわけにはいかない時もあります。
- また、手作業の手順書から思わぬヒントを得られたりすることもあります。(あるいは後継者がスマートなPlaybookを書いてくれるかもしれません)
テストを作成しよう
- Playbookでの変更をチェックするようなテストを作成すれば、必要な変更を変えないような改修が容易になります。
- Playbook作成時(もしくは作成前)にテストコードを書き始めましょう。
終わりに
- 初めてこのトピックで書いたものの、手順書とは違い正解がない気がしていて、公開前からツッコミを恐れています。。。
- Ansibleは広く知られたツールだと思いますので、この辺多くの人が考えていることかなと思います。
- 是非ワイワイ議論したいのでTwitterなりでお声掛けください。
Ansible 2.9→2.10の変更点まとめてみた
背景
- Ansible2.9から2.10でモジュールの構成が変わるという話を聞いて今後のバージョンアップに不安を感じたため、情報をまとめることにしました。
注意
- あくまで現時点での覚書です。
- 本記事は参照元の変更に従い情報更新や変更を行います。
- 参照記事を翻訳・解釈したものなので、間違ってたら指摘ください。
参照
本記事は下記ページから情報を取得しています。
概要
The 2.10 release of Ansible will fundamentally change the scope of plugins included in the ansible/ansible repository, by moving much of the plugins into smaller collection repositories that will be shipped through https://galaxy.ansible.com/ (https://docs.ansible.com/ansible/devel/roadmap/ROADMAP_2_10.html#additional-resources)
- 2.10系からは
ansible/ansible
リポジトリのリリースのスコープが変更される、というのが大まかな内容です。 - 下記ざっくりと書いてみました。
2.9系までの方針
ansible/ansible
という単一リポジトリで全てのパッケージを管理していた。
2.10系からの方針
ansible/ansible
リポジトリには下記内容のみ存在する。- 上記以外のモジュールはcollectionに移動する。
- Collectionは
ansible/ansible
と異なるタイミングでリリース可能。 - Ansibleコミュニティチームが管理するコレクションはcommunity.generalリポジトリに移動。
- Collectionは
- Ansible 2.10パッケージのリリースでは、
ansible-base
と、もともとansible/ansible
の一部だったコミュニティcollectionが組み込まれる。 - 2.10系のリリースサイクルの大半はリポジトリの構成変更によるもの
その他
- Ansibleのインストールコマンドが変更される。
-
pip install ansible-base
→Ansible(2.10)
インストール pip install ansible
→Ansible Community Distribution
(Ansible(2.10)
+ collection経由で追加のモジュール・プラグイン)インストール
-
影響
- バージョンアップ自体はこれまで通りのコマンドでいける。(モジュール入れる入れないでも変わりそうだけど)
- 必要なcollectionを洗い出しておく必要がある。
- 各モジュールのアップデートをどこまで追うか、組織での検討が必要。
所感
- インストール手順ががっつり変わるわけではなくホッとしました。(現時点でわかる範囲ですが・・・)
- モジュール単位のバージョンアップが容易になることで、嬉しい反面負荷が大きくなりそうだなあ、という印象です。
翻訳に自信がないので間違えてたら指摘ください・・・。
VSCodeでdjangoアプリケーションの実行設定を追加する
背景
- 現在↓のdjango本を読んでいます。
- 書籍中ではpycharmを使用して開発をしていますが、VSCodeでも十分だと思ったので、環境設定をVSCode用に読み替えていこうと思います。 honto.jp
今回のゴール
前提
手順
debug用のファイルであるlaunch.json
が作成されればよい。
- VSCodeの
実行
タブをクリックする。下記のような表示になるので、launch.jsonを作成する
を選択する。 - 下記の順で選択していく。
- manage.pyのパスを記入する。
- launch.jsonが作成され、実行設定が追加されていることを確認する。
メモ
- よくよく探してみたら、VSCodeのページにあるらしい。 code.visualstudio.com
VSCodeでdjango開発環境を作成する(venv)
背景
- djangoを学ぼうと思いこちらの本を読んでいたのですが、環境構築のページが古く、ちょっとつまずきました。 honto.jp
- そこで自宅環境にすでにインストールしているVSCodeを使用してdjango開発環境を作成することにしました。
想定環境
- VSCodeがインストール済みであること
- homebrewがインストール済みであること
- python3系がインストール済みであること
手順
- ありがたいことにvscodeのチュートリアルがあるので、これに沿っていきます。 code.visualstudio.com
コマンドラインでの作業
- 適当なディレクトリを作成
$ mkdir django-tutorial $ cd django-tutorial
- venvインストール
$ brew install python3-venv $ python3 -m venv (env名)
VSCodeでの作業
- [cmd]+[Shift]+[p]で[select python interpreter]を選択
- 前の手順で作成したvenv(ここではtutorial)があるので、選択
Python ... ('tutorial': env)が表示されればOK
[ターミナル]→[新しいターミナル]で開く(
(env名)host:dir user$
のように表示される)- 開いたターミナルでdjangoをインストールする
$ python -m pip install django
- djangoプロジェクト作成
$ django-admin startproject (project名)
- ↑手順で作成したプロジェクトに移動し、django appを起動
$ cd (project名) $ python manage.py runserver
参照ページのTutorialはまだまだ続きますが、環境設定はこれにて終わりです。
あとがき
GitLabとMoleculeでPlaybookのテストをしてみる
あっという間に2月になってました。 今回はGitLabとMoleculeを使用してPlaybookのCIを回してみようと言うお話です。
ゴール
- ローカル環境に同様の環境を用意し、GitLab CI上で行なっているものと同様のテストを実行できるようにする。
- GitLab CIを使用してPlaybookのテストの自動実行を実現する。
ローカル環境前提
- Mac OS
- Python3系がインストールされている
GitLab CI/Moleculeざっくり概要
GitLab CI
- GitLab CI/CDとはGitLabに備わっているCI/CDのためのツールです。
git push
等のイベントを受け、ジョブを自動実行してくれます。- GitLab CIのドキュメント: https://docs.gitlab.com/ee/ci/
Molecule
- AnsibleのRoleテスト用ツールです。
- lint、一時的な環境構築、Playbook実行、ユニットテスト実行、環境削除までの一連の流れをサポートしています。
- 今回はPlaybookのテストを行いたいと思います。多分ちょっと例外的な使い方だと思います。
ドキュメント molecule.readthedocs.io
これから作成するもの
- Molecule実行用ディレクトリ(molecule/)
- GitLab CI実行用ファイル(.gitlab-ci.yml)
- Molecule実行用イメージ(Dockerfile)
手順
ゴールはこんな感じです。
最初にローカル環境を整えます。
Moleculeインストール
- pipを使用してmoleculeをインストールします。Moleculeで使用する環境が
docker
の場合、併せてdockerをインストールします。
$ pip3 install molecule $ pip3 install docker
1. Molecule実行用ディレクトリ(molecule/)作成
初期化
molecule init
コマンドを使用してmoleculeで使用するファイル群を作っていきます。- 今回はroleのテストは行いませんので、
molecule init scenario
を使用します。
# まずはシナリオ名を指定せずにdefaultディレクトリを作成 # defaultディレクトリがないと実行できません $ molecule init scenario # 今回利用するシナリオを作成(`createuser`と言う名前にします) $ molecule init scenario -s createuser
- 作成されるディレクトリ構成はこんな感じです。
- 以降、
createuser/
以下のファイルのみを修正していきます。
molecule ├── createuser │ ├── Dockerfile.j2 │ ├── INSTALL.rst │ ├── molecule.yml │ └── tests │ ├── __pycache__ │ │ ├── test_createuser.cpython-37-pytest-5.3.5.pyc │ │ └── test_default.cpython-37.pyc │ └── test_createuser.py └── default ├── Dockerfile.j2 ├── INSTALL.rst ├── molecule.yml └── tests ├── __pycache__ │ └── test_default.cpython-37.pyc └── test_default.py
molecule.yml
molecule.yml
はmolecule実行時の設定を記述するファイルです。- lintツールやテストツールの指定等ができます。
- シナリオ作成時に作成されるファイルは下記のようになっています。
--- dependency: name: galaxy driver: name: docker lint: name: yamllint platforms: - name: instance image: centos:7 provisioner: name: ansible lint: name: ansible-lint verifier: name: testinfra lint: name: flake8
- 今回はPlaybookを下記のように修正して使用します。
--- dependency: name: galaxy driver: name: docker lint: name: yamllint # インスタンス名を変更 platforms: - name: createuser image: centos:7 # 実行するPlaybookを指定 provisioner: name: ansible lint: name: ansible-lint playbooks: converge: ../../createuser.yml verifier: name: testinfra lint: name: flake8 # シナリオ名を指定 scenario: name: createuser
テストファイル(testinfra)
- 今回は
testinfra
というテストツールを使用します。 - 接続先に対してコマンドを実行し、あるべき状態かを確認することができます。
- また、Ansibleのhostsやモジュールをサポートしており、Playbookのテストに適していると思います。
- 初期化時は下記のような状態となっています。
import os import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE'] ).get_hosts('all') def test_hosts_file(host): f = host.file('/etc/hosts') assert f.exists assert f.user == 'root' assert f.group == 'root'
- ユーザが作成されたことを確かめるよう記述します。
- 色々かけるので、詳細はドキュメントサイトを確認ください。
import os import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE'] ).get_hosts('all') def test_hosts_file(host): f = host.file('/etc/hosts') assert f.exists assert f.user == 'root' assert f.group == 'root' def test_user(host): user = host.user('testuser') assert user.name == 'testuser'
ローカル環境で実行してみる
- ここで一回ローカル環境で実行してみましょう。
- convergeで詰まった場合はdockerのインストール周りを疑ってみてください。
$ cd (moleculeディレクトリがある階層) # lint $ molecule lint -s createuser # syntax check $ molecule syntax -s createuser # 環境構築まで $ molecule converge -s createuser # unit test $ molecule verify -s createuser # 環境削除 $ molecule destroy -s createuser
2. GitLab CI実行用ファイル(.gitlab-ci.yml)作成
- CI設定は
.gitlab-ci.yml
というファイルを用いて記述します。 - 1から書き上げましょう!
--- image: registry.gitlab.com/kitiful1812/molecule-ci/molecule:latest services: - docker:dind stages: - test test-createuser: stage: test tags: - docker script: - molecule lint -s createuser - molecule syntax -s createuser - molecule converge -s createuser - molecule verify -s createuser - molecule destroy -s createuser
3. Molecule実行用イメージ(Dockerfile)作成
- 上でかいた通り、GitLab CIでジョブを実行するためにMoleculeのイメージを作成しておきます。
- ドキュメントサイトには.gitlab-ci.yml内に直接記述するようかいてありますが いちいち書くのが面倒なので、Dockerfileを作成しておきます。
FROM docker:git RUN apk update && apk add --no-cache docker \ python3-dev py3-pip docker gcc git curl build-base \ autoconf automake py3-cryptography linux-headers \ musl-dev libffi-dev openssl-dev openssh RUN pip3 install ansible molecule docker
- イメージをコンテナレジストリに登録しておきます。
$ docker build -t (イメージ名) $ docker push
- これでいつでも同じイメージを起動することができます。便利!
まとめ
- これでGitLab CI/ローカル環境で同様なテストを実現することができました!
- 是非実践してみてください。
備考
- sampleリポジトリ gitlab.com
Ansibleのコールバックプラグインの設定〜使用
背景
- Playbook実行中に必要なタスクだけ表示させたいという要件がありました。
- Twitterでつぶやいたところ、callbackプラグインが内容に合いそうだという指摘を受けたので調べてみることにしました。
目的
コールバックプラグインとは
- Ansibleジョブ実行時の表示を変化させたり、別ツールと連携させたりできるプラグインのこと。
- ansible.cfgから容易に設定が可能。
- 今回はselective pluginを使用します。
手順
コールバックプラグインを設定する
- ansible.cfgに[defaults]セクションに下記の通り記述します。
[defaults] stdout_callback = selective
Playbookを書く
- localhostに対してジョブを実行するPlaybookを書きます。
- 表示させたいタスクに
tags:[print_action]
を追加します。
--- - name: callback plugin テスト用 hosts: localhost connection: local tasks: - name: debug debug: msg: "tagなしだから表示されない" - name: debug msg debug: msg: "メッセージが表示される" tags: [print_action] - name: debug list debug: var: item loop: - "msg1" - "msg2" - "msg3" tags: [print_action]
実行結果
hogehogenoiMac:study user$ ansible-playbook main.yml .. # debug msg *************************************************************************************************************** * localhost - changed=False -- メッセージが表示される --------------------------------- # debug list ************************************************************************************************************** * localhost - changed=False -- All items completed ------------------------- * msg1 - FAILED!!! -- ------------------------------------------------ * msg2 - FAILED!!! -- ------------------------------------------------ * msg3 - FAILED!!! -- ------------------------------------------------ # STATS ******************************************************************************************************************* localhost : ok=4 changed=0 failed=0 unreachable=0
実際は色付きで表示されます。カラフル!
メモ
なんでloopを使用した際はFAILEDになるんだろう。。。と思ってたらissueにあがってた。 アップデートで解決することを祈ります。
2020年やりたいことリスト
あけましておめでとうございます。 今年も1年よろしくお願いします。
概要
2020年中にやりたいこと・やらないことを↓にあげておきます。 やりたいことは、やったら打ち消し線で消します。
リスト
やる
トコジラミ駆除埃掃除するいらない書籍を全部捨てる積ん読見える化- 積ん読消化
- LPIC Level1取得
- LPIC Level2取得
- minishiftでテキスト学習
- vue.js書籍読む
Python書籍読むPythonで何らかのスクリプトを書いてGitHubで公開する- はてなブログの更新を月1
- Ansibleを題材になんか書く
- 勉強会への参加
- 楽団移籍
- フルートアンサンブルの発表の場を設ける
フルートレッスン行ってみる他楽団の人と仲良くなる- 旅行
- 参加する同人イベントの可視化
- 背景描写の克服
- 1Pでもいいから月1で漫画を描く
- 通勤・退勤時間に読書をする
やらない
- 無駄な飲み会
- 残業
- 浪費
- 料理の作りすぎ
- 暴飲暴食
やらない項目はこれから増えていきそう。。。
備考
- 積ん読絶賛公開中です。