てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] --vault-password-file で指定するファイルはスクリプトでも可なので環境変数も参照できる

--vault-password-file オプションとは

Ansible にはパスワードなどの機密情報を暗号化する ansible-vault という機能があります。

Playbook 実行時には何かしらの方法で復号パスワードを指定する必要があります。ansible-playbook コマンドにも関連オプションがいくつかあります。

パスワードを書いたファイル名を指定するには --vault-password-file というオプションがあります。

テキストだけでなくスクリプトも指定可

最近知ったのですが、この --vault-password-file オプションは、パスワードを書いたテキストファイルだけでなく、パスワードを標準出力する.py などスクリプトも指定できます。

公式ドキュメントには以下のコマンド例があります。

ansible-playbook --vault-password-file my-vault-password-client.py

別システムに格納されたパスワードをとってきて利用するなんてこともできそうですね。

工夫次第で環境変数の参照も可

この性質を利用すると、パスワードを環境変数に仕込んでそれを参照することもできるようです。以下のサンプルをみたときに、なるほど!と思いました。

Ansible Vault Environment Variable · GitHub

実行権限を与えることお忘れなく。

[ansible] ansible-navigator で --step や vars_prompt によるインタラクティブな操作をする

はじめに

ansible-navigator は、Playbookの実行、ドキュメントなどの情報が表示できる TUI ツールです。

Playbook の実行に関しては、ansible-playbook コマンドでできることはだいたいできると思ってよさそうです。 ansible-playbook コマンドの各オプションも ansible-navigator コマンド経由で渡るようです

ただし、ユーザーからの操作を受けてのインタラクティブな操作が一部できません。

私が分かっている範囲では、--step オプションによる Playbook のステップ実行や、vars_promptディレクティブによる変数の値の入力などです。Playbook の実行が途中で止まることは止まりますが、ユーザーの入力値を拾ってくれません。

何かか対処方法はあるかなと調べたらたら、ドキュメントの Frequently asked questions に掲載されていました。

playbook-artifact を無効化して、モードを stdout にするといいようです。

試してみたのでまとめます。

  • 環境
    • ansible-navigator 1.1.0

playbook-artifact の無効化と、stdout モードへの変更

デフォルトでは playbook-artifact が有効で、モードは interactive (TUI) なのでそれぞれ変更する必要があります。

挙動の指定方法は以下の3通りあります。

  1. ansible-navigator の設定ファイルである ansible-navigator.yml による指定
  2. ansible-navigator コマンドのオプションによる指定
  3. 環境変数による指定

各設定値や方法詳細はこちら

指定方法1: ansible-navigator.yml

ansible-navigator.yml による指定の場合は、以下のように定義します。

---
ansible-navigator:
   # ...(略)...
   playbook-artifact:
     enable: False       # playbook-artifact の無効化
   mode: stdout         # モードを stdout に変更

指定方法2: ansible-navigator コマンドのオプション

オプション 説明 指定例
--pae または --playbook-artifact-enable playbook-artifact の有効、無効 --pae False
-m または --mode モードの指定 -m stdout

指定方法3: 環境変数

export ANSIBLE_NAVIGATOR_PLAYBOOK_ARTIFACT_ENABLE=False
export ANSIBLE_NAVIGATOR_MODE=stdout

おためし1: --step によるステップ実行

ここでは ansible-navigator コマンドのオプション(-m stdout --pae False)で指定します。加えて、ステップ実行の --step オプションも指定します。

$ ansible-navigator run plyabooks/step.yml -i inventory --step -m stdout --pae False
PLAY [localhost] **********************************************************************************
Perform task: TASK: task1 (N)o/(y)es/(c)ontinue: y   # ここで一時停止するので、実行するための y を指定してエンター

Perform task: TASK: task1 (N)o/(y)es/(c)ontinue: **************************************************

TASK [task1] **************************************************************************************
ok: [localhost] => {
    "msg": "this is task1"
}
Perform task: TASK: task2 (N)o/(y)es/(c)ontinue: y  # 同上

Perform task: TASK: task2 (N)o/(y)es/(c)ontinue: **************************************************

TASK [task2] **************************************************************************************
ok: [localhost] => {
    "msg": "this is task2"
}

PLAY RECAP ****************************************************************************************
localhost  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

参考: playbook-artifact を有効なままの場合

なお、playbook-artifact を有効なままの場合、以下のところでとまって入力も受け付けられません。(さすがにCtrl+Cで抜けられます)

$ ansible-navigator run plyabooks/step.yml -i inventory --step -m stdout  # playbook-artifact を有効なまま

PLAY [localhost] ***************************************************************

おためし2: vars_prompt による変数値指定

以下の Playbook で試します。

---
- hosts: localhost
  gather_facts: false
  connection: local

  vars_prompt:   # 変数の値をインタラクティブにユーザーに指定してもらう
    - name: msg
      prompt: Input msg
      private: false

  tasks:
    - name: task1
      ansible.builtin.debug:
        msg: "{{ msg }}"

先ほどと同じく、 ansible-navigator コマンドのオプション(-m stdout --pae False)で指定します。

$ ansible-navigator run plyabooks/step.yml -i inventory  -m stdout --pae False
Input msg: sakana sakana sakana         # 変数の値を聞かれるので入力する

PLAY [localhost] ***********************************************************************************

TASK [task1] ***************************************************************************************
ok: [localhost] => {
    "msg": "sakana sakana sakana"
}

PLAY RECAP *****************************************************************************************
localhost   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

参考: playbook-artifact を有効なままの場合

playbook-artifact を有効なままの場合、以下のところでとまって入力も受け付けられません。(さすがにCtrl+Cで抜けられます)事情を知らないと何が起こったかわからないですね・・

$ ansible-navigator run plyabooks/step.yml -i inventory  -m stdout 

--stepvars_prompt を別々で試しました、組み合わせも大丈夫でした。

おわりに

今回ご紹介した設定変更では、当初とは別の制約があります。

  • playbook-artifact を無効化するため ansible-navigator replay によるリプレイ機能が利用できない
  • stdout モードにするためTUI ではなくなる

だったら普通に ansible-playbook コマンドでいいんじゃないかというケースもありますが、Execution Environment をコマンドから使うにはやはり ansible-navigator を使うことになると思います。

上記2点の制約が特に問題ではなく、インタラクティブな操作が必要な場合は、有効な手段になるかと思います。

JANOG49 Meeting in Kagoshima 参加レポート

はじめに

2022/01/26-28 に鹿児島県鹿児島市で開催(オンラインとハイブリッド)された JANOG49 Meeting にオンラインで参加しました。

見たプログラムについて、感想やメモ書きレベルですが残しておきます。

資料は公開されているので、気になったプログラムがあればリンク先から詳細をご覧いただければと思います。

アーカイブは2022/03/07まで公開予定とのことです(JANOG ML [janog:15225] (JANOG49)アンケートとアーカイブ配信について より)。


■ Day1

ネットワーク運用自動化(NetOps)の実運用: 苦労/解決/妥協した話

www.janog.gr.jp

P14 で、設計で意識しないといけなかったこととして、以下2点があげられていました。

  • 事業の特性
  • 要員の特性

「他社の正解事例が自社の正解とは限らない」というのは悩ましい話だなと思いました。自分たちのことを知る、というのは思いのほか難しそうです。

P24では、作業全体の自動化は難しいと語られていました。完璧を求めないための視点は重要そうです。

P26、今後の展望の一つは検証の自動化や効率化とのことでした。検証、判定自体は、本来は人間よりも機械が得意とする類のものもだとは思うのですが、組み合わせが多くなると、作り込みが大変になりそうですね・・。

本プログラム全体としては、自分たちを知ることと、落とし所が重要なのだと感じました。

モバイルバックホール作業自動化への挑戦

www.janog.gr.jp

P8、作業自動化 拡大の "本当の" 壁として、以下3点が挙げられていました。

  • 作業品質の低下
  • ノウハウの属人化
  • 保守的な環境

これらを乗り越えるために、実行環境の整備や、マニュアルの作成、ハンズオンの開催などをされたそうです。取っ付きやすいマニュアルの作成というのは個人的に盲点でした。

P14、自動化拡大のために重要なのは「ストレスフリーな環境作り」。使うのは人間なので、こういうところに働きかけるのは重要なのだなと思いました。

■ Day2

Clos Network Topology を運用するために、どのような取り組みをしていますか

www.janog.gr.jp

プログラムの内容そのものもとても素晴らしかったですし、質疑応答や Slack でのやりとりもとても良かったです。

JANOG Meeting では、発表者と参加者という区切りはあるものの、二者間で質疑応答したり、議論したりします。このプログラムではさらに、Slack 内での参加者同士の意見交換も活発で、いいなと思いました。Clos アーキテクチャに限定しない、教育やオンボーディングに関する話が多かった印象でした。

今更ながらRFC5549でIXピアしてみよう

www.janog.gr.jp

参加者から RFC 5549 のとある箇所の解釈についての意見が出てきて、数人で意見交換されていました。こういう場があるのもなんだかいいですね。

■ Day3

L1トラブルシューティング

www.janog.gr.jp

ケーブルの天敵の一つはセミだそうです。セミが卵を生んでしまうそうです。知らなかった・・。

NETCON Wrap-up

www.janog.gr.jp

自動採点の仕組みがすごいなと思いました。

クラウドオペレーティングモデルはネットワークの世界でどこまでできるか?

www.janog.gr.jp

私はよく Ansible を利用するのですが、ときどき Terraform のような宣言的な指定をしたくなります。 ネットワーク関連の Provider の今後の動向に注目していきたいと思います。

KDDI固定電話ネットワーク、NFV化の5年間の道のり

www.janog.gr.jp

P35の「オープンソース利用の見極め」。PoCのPoCというのは、なんとなくやっていたことではありますが、言語化するとたしかにそうかも知れないという納得感がありました。いきなり実運用を見据えた検討は難しいでしょうし、まずは物を知るというステップを明示的に設けるのは良いなと思いました。

一番印象的だったのが P37 の所感です。

運用の課題は、運用しないとわからないから
完璧を目指すより「改善しやすい仕組み」「管理しやすいルール」
「運用者が改善にガッツリ取り組める雰囲気」が必要だと感じた

単なる「やってみないとわからない」だけでなく、改善、管理、仕組みを見据えた観点がとても参考になりました。

閉会宣言/次回予告

www.janog.gr.jp

本編ではないですが、式が始まる前のスタッフさん同士の会話が、ラジオのようで心地よかったです。

■ おわりに

今回もハイブリッド開催となりました。かなり難易度高いのではないでしょうか・・。感謝です。

いつも登壇者の皆様、スタッフ皆様、ホストや協賛各社様、ありがとうございます!

特に、今回は新しい取り組みとして、アーカイブ公開がかなり早くてありがたかったです。見逃した人に紹介するときも紹介しやすかったです。

次回の JANOG50 Meeting は 2022/07/13 - 15 に北海道で開催予定です。

おまけ

私と JANOG

Azure の公式ドキュメントを修正してみた

はじめに

Azure の公式ドキュメントには、Ansible から操作するための情報が多く載っていてありがたいです。

docs.microsoft.com

眺めていたら、Get Started: Configure Ansible on an Azure VMというページで、インデントがおかしいところがありました。

f:id:akira6592:20220202090558p:plain
インデントがおかしい箇所が複数

気になって修正方法を調べました。

これまたありがたいことに、twitterで詳細をおしえていただきました

おかげさまで、実際に修正までできたので、そのときのことをまとめます。

修正とプルリクエス

修正の基本的な流れは、以下のページに掲載されていまる。

docs.microsoft.com

GitHub アカウントがあれば、プルリクエストを出した経験がない方でもわかるくらいのていねいな説明になっています。

上記のページでは、暗黙的に fork してブランチ作成する手軽な手順になってます。この場合、patch-1 というブランチになるのですね。

もちろん、明示的に fork してはじめても良いはずです。

出したプルリクエストがこちら。

github.com

CLA の同意

プルリクエストを出した後に、他のページにも類似のインデント誤りがあったので修正してコミットしました。

すると、microsoft-cla bot さんから、CLA(Contribution License Agreement)同意お願いのコメントがつきました。

共同作成者ガイドにも書かれていましたが、

お客様が Microsoft の従業員ではない場合、新規または大幅な変更を加えると、オンラインの貢献者使用許諾契約書 (CLA) のご提出をお願いするコメントが pull request 内に生成されます。

に該当したようです。

内容を確認し、とくに問題なかったので同意しました。

すると、signed に更新されました。

f:id:akira6592:20220202090126p:plain
CLA同意済み

マージ

修正内容にも特に問題なかったようで、暫く待つと main ブランチにマージしていただきました。

反映

翌日には無事に、ドキュメント上にも反映されていました。

f:id:akira6592:20220202090705p:plain
インデント修正が反映された

ちょっとした修正でしたが、この記事にコントリビュートした人の一覧に載って嬉しいです。

f:id:akira6592:20220202090833p:plain
コントリビューター

終わりに

思いの外簡単にできました。

もしまた自分に修正できそうなところがあったら、またやってみたいと思います。

docs.microsoft.com

[Ansible/Azure] azure_rm インベントリプラグインでインベントリ名を仮想マシン名に合わせる

はじめに

azure.azcollection.azure_rm というインベントリプラグインは、AzureのVMの情報を動的に取得できます。

対象のリソースグループ名やグループ化の仕方、変数の持ち方などをYAMLで定義します。

このインベントリプラグイン利用時に、インベントリ名(inventory_hostname)を仮想マシン名にする方法を紹介します、

  • 動作確認環境
    • ansible 5.1.0 (ansible-core 2.12.1)
    • azure.azcollection collection 1.10.0

デフォルトでは?

デフォルトでは、インベントリ名は 仮想マシン名_4文字 のようになります。

仮想マシン名は、仮想マシンをポータルで作成する画面でいう「仮想マシン名」です。

4文字のところは、仮想マシンのID(/subscriptions/サブスクリプションID/resourceGroups/リソースグループ名/providers/Microsoft.Compute/virtualMachines/仮想マシン名)をもとにしたハッシュ値の最初の4文字です。

リソースグループが別だと同じ仮想マシン名が許容されるので、競合させないための工夫のようです。

ですが、設計上全リソースグループ内で仮想マシン名をユニークにしていたり、include_vm_resource_groups パラメーター で対象リソースグループを制限している場合などでは仮想マシン名は競合せず、インベントリ名を仮想マシン名に合わせたいケースもあるかもしれません。

仮想マシン名に合わせる機能は、インベントリプラグインとしては後から追加され、実装上はAzure rm legacy hostnames と呼んでいたようです。

インベントリ名を仮想マシン名にするサンプル

インベントリ名を仮想マシン名にするには、以下のように、plain_host_names オプションに、true を指定します。

  • inventory_azure_rm.yml
plugin: azure.azcollection.azure_rm
include_vm_resource_groups: # (参考) 対象リソースグループ名、デフォルトはすべて
  - ansible_azure
plain_host_names: true      # インベントリ名を仮想マシン名にする
conditional_groups:         # (参考) 動的なグループ定義
  windows: "'WindowsServer' in image.offer"

なお、ファイル名は公式ドキュメントにあるように、ファイル名を azure_rm.(yml|yaml) で終わるようにします。

実行例

インベントリ名を書くにするために、debug モジュールで、"I am {{ inventory_hostname }}" を出力するだけのPlaybookを実行します。ここでは、ansible01仮想マシン名です

$ ansible-playbook -i inventory_azure_rm.yml debug.yml

PLAY [all] ************************************************************************************************************

TASK [debug inventory_hostname] ***************************************************************************************
ok: [ansible01] => {
    "msg": "I am ansible01"
}

PLAY RECAP ************************************************************************************************************
ansible01                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

インベントリ名を確認するだけなら、Playbookは実行せずに ansible-inventory コマンドを利用すのが便利です。

$ ansible-inventory -i inventory_azure_rm.yml --graph
@all:
  |--@ungrouped:
  |--@windows:
  |  |--ansible01

なお、デフォルトである plain_host_names: false の場合は、以下のようにインベントリ名は 仮想マシン名_4文字 になります

$ ansible-inventory -i inventory_azure_rm.yml --graph
@all:
  |--@ungrouped:
  |--@windows:
  |  |--ansible01_d165

別解

以下のように、hostaname オプションで name を指定することでも、結果的には同じ挙動になります。

# ...略...
hostnames:  
   - name

より意図を示すためには、plain_host_names オプションを利用するほうが良いかと思います。

[Ansible] 2021年のAnsibleリリースまとめ

はじめに

2020年は、ansible-base (現 ansible-core) と collection に分かれての配布が始まったことが大きな出来事でした。

2021年も、ansible-core も、コミュニティが選別したcollectionをセットにしたパッケージもそれぞれアップデートされていきました。

また、 Red Hat Ansible Automation Platform (AAP) 2.X のリリースも大きかったと思います。

2021年の重要だと感じたリリースを簡単にまとめます。

2月

ansible 3.0.0 リリース

バージョン体系を変更してからの最初のリリース。

3月

AWX 18.0.0 リリース

docker-compose ではなく、AWX Operator によるインストール方法が優先に。

個人的にはこれ以降インストールを試していません・・。

github.com

4月

ansible-core 2.11.0 リリース

zenn.dev

5月

ansible 4.0.0 リリース

ansible-core は 2.11 系。

zenn.dev

7月

Red Hat Ansible Automation Platform 2.0 (Early Access) リリース

Ansible Tower が Automation Controler に改称。 その他、実行環境がコンテナベースになるという大きなアーキテクチャ変更。 関連ツールは、ansible-nabigator、ansible-runner、ansible-builder。

11月

ansible-core 2.12.0 リリース

コントロールノードで Python 3.8 以上が必要に。

zenn.dev

12月

ansible 5.0.0 リリース

ansible-core は 2.12 系。 zenn.dev

Red Hat Ansible Automation Platform 2.1 リリース

関連 www.ansible.com

おわりに

2022年はどのようなことが起こるのでしょうか。

個人的には、コンテナベースの実行環境の利用が進んでいくような予感がしています。

[Ansible] ansible-plyabook コマンドでインベントリを複数指定する

はじめに

ansible-playbook コマンドの -i オプションは複数のインベントリを指定できます。

ansible-playbook -i inventory01.ini -i inventory02.ini playbook.yml 

この記事ではかんたんなサンプルと実行例を紹介します。

  • 動作確認環境
    • ansible 5.1.0 (asnble-core 2.12.1)

サンプル

インベントリファイルの用意

インベントリファイルを2つ用意します。分かりやすくするため、1つめに group01、2つめに group02 を定義します。

  • inventory01.ini
[grouop01]
router101
router102
  • inventory02.ini
[grouop02]
server201
server202

合計、4台のホストです。

Playbookの実行

hosts: all にした適当なPlaybookを実行します。

$ ansible-playbook -i inventory01.ini -i inventory02.ini test.yml

PLAY [all] **************************************************************************

TASK [debug inventory_hostname] *****************************************************
ok: [router101] => {
    "msg": "I am router101"
}
ok: [router102] => {
    "msg": "I am router102"
}
ok: [server201] => {
    "msg": "I am server201"
}
ok: [server202] => {
    "msg": "I am server202"
}

PLAY RECAP ***************************************************************************
router101  : ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
router102  : ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
server201  : ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   
server202  : ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   

2つのインベントリに含まれる4台のホスト分が実行されました。

Playbookを実行せずにホスト一覧を確認する

Playbookを実行せずとも、ホストの確認だけなら他の方法もあります。

ansible-playbook--list-hosts オプションを利用する方法。こちらでは、Playbookが hosts: all なので、全部出力されます。

$ ansible-playbook -i inventory01.ini -i inventory02.ini test.yml --list-hosts

playbook: test.yml

  play #1 (all): all    TAGS: []
    pattern: ['all']
    hosts (4):
      server201
      router101
      router102
      server202

ansible-inventory というインベントリ確認用のコマンドも便利です。

@all:
  |--@grouop01:
  |  |--router101
  |  |--router102
  |--@grouop02:
  |  |--server201
  |  |--server202
  |--@ungrouped:

少し応用(スタティックとダイナミックの組み合わせ)

先程ほどのサンプルは、スタティックなインベントリを複数していました。スタティックとダイナミックの組み合わせもできます。

ここでは、AzureのVMの情報を利用できる azure.azcollection.azure_rmインベントリプラグインを利用するインベントリを、2つめに指定します。

$ansible-inventory -i inventory01.ini -i inventory_azure_rm.yml --graph 
@all:
  |--@grouop01:
  |  |--router101
  |  |--router102
  |--@rg_ansible_azure:
  |  |--azure01_7192
  |--@ungrouped:
  |--@windows:
  |  |--azure01_7192

rg_ansible_azurewindows グループが、azure.azcollection.azure_rm インベントリプラグインで取得したものです。