腐女子エンジニアの日記

創作と技術と時々音楽

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の機能をうまく使用してシンプルに・わかりやすく書きましょう。
    • 前のバージョンのドキュメントですが、おすすめです。

docs.ansible.com

手作業の手順書を残そう

  • 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リポジトリには下記内容のみ存在する。
    • core ansible programs(ansible-{playbook, galaxy, doc, test} etc...)
    • ドキュメント
    • コントローラで機能可能なモジュール・プラグインの小さなサブセット
    • ansible-base(anible/ansibleのdevelブランチのこと)
  • 上記以外のモジュールはcollectionに移動する。
    • Collectionはansible/ansibleと異なるタイミングでリリース可能。
    • Ansibleコミュニティチームが管理するコレクションはcommunity.generalリポジトリに移動。
  • Ansible 2.10パッケージのリリースでは、ansible-baseと、もともとansible/ansibleの一部だったコミュニティcollectionが組み込まれる。
  • 2.10系のリリースサイクルの大半はリポジトリの構成変更によるもの

その他

  • Ansibleのインストールコマンドが変更される。
    • pip install ansible-baseAnsible(2.10)インストール
    • pip install ansibleAnsible Community Distribution(Ansible(2.10) + collection経由で追加のモジュール・プラグイン)インストール

影響

  • バージョンアップ自体はこれまで通りのコマンドでいける。(モジュール入れる入れないでも変わりそうだけど)
  • 必要なcollectionを洗い出しておく必要がある。
  • 各モジュールのアップデートをどこまで追うか、組織での検討が必要。

所感

  • インストール手順ががっつり変わるわけではなくホッとしました。(現時点でわかる範囲ですが・・・)
  • モジュール単位のバージョンアップが容易になることで、嬉しい反面負荷が大きくなりそうだなあ、という印象です。

翻訳に自信がないので間違えてたら指摘ください・・・。

VSCodeでdjangoアプリケーションの実行設定を追加する

背景

  • 現在↓のdjango本を読んでいます。
  • 書籍中ではpycharmを使用して開発をしていますが、VSCodeでも十分だと思ったので、環境設定をVSCode用に読み替えていこうと思います。 honto.jp

今回のゴール

  • VSCodedjangoの実行設定を行う。
  • VSCode上で「実行」をクリックした際、python manage.py runserverが実行されればOK。

前提

  • VSCodeでvenv環境がactivateされていること。されていないとdjangoをよびだせない。
  • djangoアプリケーションディレクトリが作成されていること。

手順

debug用のファイルであるlaunch.jsonが作成されればよい。

  1. VSCode実行タブをクリックする。下記のような表示になるので、launch.jsonを作成するを選択する。 f:id:dcn_f:20200513235901p:plain
  2. 下記の順で選択していく。
    f:id:dcn_f:20200513235904p:plain
    pythonを選択
    f:id:dcn_f:20200513235907p:plain
    Djangoを選択
  3. manage.pyのパスを記入する。 f:id:dcn_f:20200513235910p:plain
  4. launch.jsonが作成され、実行設定が追加されていることを確認する。 f:id:dcn_f:20200513235913p:plainf:id:dcn_f:20200513235917p:plain

メモ

VSCodeでdjango開発環境を作成する(venv)

背景

  • djangoを学ぼうと思いこちらの本を読んでいたのですが、環境構築のページが古く、ちょっとつまずきました。 honto.jp
  • そこで自宅環境にすでにインストールしているVSCodeを使用してdjango開発環境を作成することにしました。

想定環境

  • VSCodeがインストール済みであること
  • homebrewがインストール済みであること
  • python3系がインストール済みであること

手順

コマンドラインでの作業

$ mkdir django-tutorial
$ cd django-tutorial
  • venvインストール
$ brew install python3-venv
$ python3 -m venv (env名)

VSCodeでの作業

  • python拡張機能をインストールする f:id:dcn_f:20200413235434p:plain

  • コマンドラインでの作業時に作成したディレクトリを開く

  • [cmd]+[Shift]+[p]で[select python interpreter]を選択 f:id:dcn_f:20200413235857p:plain
  • 前の手順で作成したvenv(ここではtutorial)があるので、選択 f:id:dcn_f:20200413235944p:plain
  • Python ... ('tutorial': env)が表示されればOK  f:id:dcn_f:20200414000131p:plain

  • [ターミナル]→[新しいターミナル]で開く((env名)host:dir user$のように表示される)

  • 開いたターミナルでdjangoをインストールする
$ python -m pip install django
  • djangoプロジェクト作成
$ django-admin startproject (project名)
  • ↑手順で作成したプロジェクトに移動し、django appを起動
$ cd (project名)
$ python manage.py runserver

参照ページのTutorialはまだまだ続きますが、環境設定はこれにて終わりです。

あとがき

  • djangoの入門本はまだまだ少ない気がします。
  • ↓の本も面白そうだなと思っているので読んだことある人は感想を教えてください。 honto.jp

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

これから作成するもの

  1. Molecule実行用ディレクトリ(molecule/)
  2. GitLab CI実行用ファイル(.gitlab-ci.yml)
  3. Molecule実行用イメージ(Dockerfile)

手順

ゴールはこんな感じです。 f:id:dcn_f:20200210135303p:plain

最初にローカル環境を整えます。

Moleculeインストール

  1. 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のテストに適していると思います。

testinfra.readthedocs.io

  • 初期化時は下記のような状態となっています。
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/ローカル環境で同様なテストを実現することができました!
  • 是非実践してみてください。

備考

Ansibleのコールバックプラグインの設定〜使用

背景

  • Playbook実行中に必要なタスクだけ表示させたいという要件がありました。
  • Twitterでつぶやいたところ、callbackプラグインが内容に合いそうだという指摘を受けたので調べてみることにしました。

目的

コールバックプラグインとは

  • Ansibleジョブ実行時の表示を変化させたり、別ツールと連携させたりできるプラグインのこと。
  • ansible.cfgから容易に設定が可能。
  • 今回はselective pluginを使用します。

docs.ansible.com

手順

コールバックプラグインを設定する

  • 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

実際は色付きで表示されます。カラフル! f:id:dcn_f:20200106224429p:plain

メモ

なんでloopを使用した際はFAILEDになるんだろう。。。と思ってたらissueにあがってた。 アップデートで解決することを祈ります。

github.com

2020年やりたいことリスト

あけましておめでとうございます。 今年も1年よろしくお願いします。

概要

2020年中にやりたいこと・やらないことを↓にあげておきます。 やりたいことは、やったら打ち消し線で消します。

リスト

やる

  • トコジラミ駆除
  • 埃掃除する
  • いらない書籍を全部捨てる
  • 積ん読見える化
  • 積ん読消化
  • LPIC Level1取得
  • LPIC Level2取得
  • minishiftでテキスト学習
  • vue.js書籍読む
  • Python書籍読む
  • Pythonで何らかのスクリプトを書いてGitHubで公開する
  • はてなブログの更新を月1
  • Ansibleを題材になんか書く
  • 勉強会への参加
  • 楽団移籍
  • フルートアンサンブルの発表の場を設ける
  • フルートレッスン行ってみる
  • 他楽団の人と仲良くなる
  • 旅行
  • 参加する同人イベントの可視化
  • 背景描写の克服
  • 1Pでもいいから月1で漫画を描く
  • 通勤・退勤時間に読書をする

やらない

  • 無駄な飲み会
  • 残業
  • 浪費
  • 料理の作りすぎ
  • 暴飲暴食

やらない項目はこれから増えていきそう。。。

備考

booklog.jp