これからAnsibleを勉強する際におさえておきたいこと


概要

これからAnsibleを勉強される方で以下のポイントをおさえていれば、効率的に勉強できるかと思います

入り口

入り口はやはり体系的に情報がまとまっている書籍がお勧めです

公式ベストプラクティス

各種リソースのファイル構成や命名規則などが記載されています
それ以外はトライ&エラーで自分たちにあったモノを見つけていくことになります

最低限公式のベストプラクティスを読みましょう
https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html

さくらインターネットさんが公開している
実践!Ansibleベストプラクティス(前編)
実践!Ansibleベストプラクティス(後編)

Think IT
より実践的なPlaybookを作り上げる

Qiita
Ansible オレオレベストプラクティス

それなりのシステム規模になるなら

必ず命名規則を作りましょう
Ansibleに限らず規模が大きくなるとソース管理が課題になります
一定の規約を設けて管理することをお勧めします

規約例)

code_policy.md

- タスクやプレイブック内で宣言した変数は**アンダースコア**から開始する変数名にすること(`_xxx`)
- `register`の変数名は`_result_xxx`とする
- 変数名、ロール名、playbook名、ファイル名、タスク名の命名規則はスネークケースとする(Ansibleの規約)
- 変数名の開始文字列に **`ansible_`を使用してはならない**(Ansibleの予約変数名)
- jinja2テンプレートはファイル名に`j2`を含めること(区別するため)
- 環境ごとに変数の階層分けする場合は、以下のように命名すること
    - 本番用:`prd`
    - 本番検証用:`prd_dev`
    - システム管理用(ansible、zabbix):`sys`
    - ステージング環境の場合は、ファイル名に`prd`(本番)、`dev`(開発)
- YAMLファイルの先頭行は`---`を必須
- 変数ファイルはYAMLファイルを用いる(JSONはコメントを記載できないため、不採用)
- 機密情報(パスワード、アクセストークンなど)は情報漏えいを防ぐために**ansible vault**で暗号化する(作成方法は別紙参照)
- タスク名の先頭はそのタスクが属性を表すものとする<br/>
    例)<br/>
    ```
    # AWS関連の場合
    tasks/aws_xxx.yml
    # アプリ関連の場合は
    tasks/app_xxx.yml
    ```
- 実行ログでどのタスクなのかがわかるように`name`を付与する
- whenで同一変数に対して複数のor条件を指定する場合は、`in list`を用いること<br/>
    ```
    # NG
    - debug:
        msg: "test"
      when: myvar == "test1" or myvar == "test2" or myvar == "test3"

    # OK
    - debug:
        msg: "test"
      when: myvar in ["test1", "test2", "test3"]
    ```
- whenのand条件の場合は、以下のようにリスト形式で記載すること<br/>
    ```
    - debug:
        msg: "test"
      when:
        - myvar == "test1"
        - myvar2 == "test2"
        - myvar3 == "test3"
    ```
- jinjaテンプレート内のコメントは`{#- hogehoge -#}`を使用すること<br/>
    ```
    - set_fact:
        _hoge: >-
          {#- hogeを作成 -#}
    ```
- AWSリソースのタグキーはスネークケースとし、各単語の最初を大文字とする<br/>
    固有名詞や略語は、すべて大文字で可とする
    ```
    Name: hoge
    APP_Version: 5.1.1
    ```

## 自作モジュール
- モジュール名の接頭語に`hoge_`とすること
- 冪等性を担保するような実装にすること
    (すでに状態を満たしている場合は、処理をしない)
- 適宜にコメントを残すこと(特にビジネス条件にかかわる部分)

すでにDockerを使っているなら

環境をすぐに破棄することができるDockerコンテナで勉強すると効率的
また、複数台や種類(Centos、Ubuntuなど)の環境も容易に準備できる点も魅力
Qiita「Docker内でAnsibleの勉強をしよう

認証情報を扱うならば

必ずAnsible Vaultで暗号化しよう
これで認証情報もソースコードにコミットしても安心

対話形式のインストーラを扱うならば

expectモジュールを使いましょう!
忘れずに実行環境でpythonのpexpectをインストール

ハマリポイントに気を付けてください
【小ネタ】Ansible expect モジュールの罠

楽したい。既存コードを参考にしたい

Ansible Galaxyを使用しましょう!
さまざまなコードが公開されていて、ansible-galaxyコマンドですぐに使用できる

実運用でAnsibleを使用するならば

AWXもしくはAnsible Towerを必ず導入しましょう
GUIでAnsibleを操作でき、実行履歴、実行権限の制御、他システム連携が容易なRestAPIなどが利用できる
機能的にAWX=Ansible Towerであるが、サポート有や安定性が優れているのがAnsible Towerです
経済的に余裕がある場合は是非Ansible Towerの導入を検討してください

参考:
- 「Docker版AWXの構築方法
- 「高可用性のAWXをAWSで構築する方法
- 「AWX17.xをクラスタ(HA)構成にする方法

API経由で渡される変数は処理中に上書きできない!

AWXやAnsible TowerのAPI経由で渡される変数はextra vars扱い(最優先の変数)で処理中にその変数を上書きすることができない
ただし、存在しないキーを追加したり、変更することはできる
ローカルで動いたが、AWXやTower上で動かないことがあるので要注意!

変数の優先順位

変数

ある程度慣れてくると動的に変数を作るケースが増えます
そんな時に「これだけ覚えとけばもう怖くないAnsibleの(動的)変数

自作モジュール

たいていのことはAnsibleで提供されているが、自作しなければならない時は怖気ずに「Ansibleのモジュール開発」を順に読んでいきましょう
非常に簡単にできる!

参考:aws向けAnsible自作モジュールを作る

デフォルトはAll or Nothingではない

Ansibleのタスク実行は同一タスクを複数ホストに対して並列処理されます
デフォルトの設定ではすべてのホストがエラーにならないと処理が中断しない
なので、デフォルトのままだとどれかのホストでエラーが発生してもスルーされますので、危険です!

all or nothingにするためには、エラーの許容量をmax_fail_percentageで定めることができる
必ず設定しておくことをお勧めします!
ただし、操作対象のホストに到達不可の場合はエラーと見なさないので、any_errors_fatalを利用しましょう!

APIコール系のモジュールには必ずリトライ処理(もしくはパラメータ)を追加しましょう!

APIをコールして何かする系のモジュールでは、コール先がコール制限(1秒間にコールできる数)やネットワークの品質によるエラーになることが割とあります。そのたびに処理が中断されるのもつらいので、冪等性を担保しつつリトライ処理を実装しましょう!(※ここで言う冪等性はリトライ処理した分だけリソースが追加されないようにということです)

以下の3つの対策

  1. 自作モジュールの場合は、リトライ処理をモジュール内に実装
  2. 公式モジュールの場合は、retriesパラメータが用意されているのあれば、設定しましょう!
  3. untilを用いてリトライ処理も可能

開発環境

VSCodeで開発するならば「Ansible開発環境はこれで決まり! for VSCode」でOK(特にWindowsユーザにおすすめです)
Dockerを使用しますが、Dockerのことを意識せずに使える

これから始めるならAnsible 2.10.xを使いましょう!

2.10.x未満と2.10.xでモジュールの構成がガラっと変わっています。

AWSのEC2のモジュールを例に

2.9.xまではec2モジュール

- ec2:
    key_name: mykey
    instance_type: t2.micro    

2.10.xからamazon.aws.ec2モジュール

- amazon.aws.ec2:
    key_name: mykey
    instance_type: t2.micro

2.9.xまでは多くのモジュールがAnsibleのリポジトリでかんりされていましたが、それらをモジュールごとに分離されました。
AWS関連のモジュールはこちらで管理するようになりました。
一応2.10.xで2.9.xのモジュール名も動作するようですが、すべてが動作保証されているわけではないので、これから始めるのであれば2.10.xで覚えたほうがよいでしょう!

参考1:Ansible 2.9→2.10の変更点まとめてみた
参考2:Ansible 2.10 の変更点: 付属モジュールのAnsible Collectionへの移行

Python3で始めましょう!

Python2のサポートが切れているため、AnsibleもPython3対応が必要です!
基本的にAnsibleが動作する環境と操作対象端末でPython3の導入が必須になります。

※Python2で動作しなくなるわけではなく、あくまでサポート切れしているので組織内で対応を決めて対応しましょう!

参考:AnsibleをPython2.xからPython3.xに対応させる手順とトラブルシューティング

AWSのEC2接続用SSMプラグインを考えているなら要注意!

普段使いならEC2にSSH接続しますが、認証情報の管理をすべてAWSに統合し、SSH鍵の管理から解放する意図でSSMプラグインに切り替えるのも一つの選択肢です。ただし、同時接続ノード(30以上)が多い場合は、SSMの利用はお勧めしません。
理由としては、SSM接続時にAWS APIをコールするのですが、そのAPIコールレートの制限に抵触し、エラーになります。

不安!聞ける人がいない

大丈夫!日本のAnsibleユーザコミュニティ(Slack)がありますので、お気軽に質問してください!
レスポンスもよく、安心の日本語で回答してくれます