てくなべ (tekunabe)

ansible / network automation / 学習メモ

docker-compose.yml の内容を上書きする docker-compose.override.yml

はじめに

最近、netbox-docker の README.md を見て知ったのですが、docker-compose.yml の内容を上書きする docker-compose.override.yml というファイルがあるそうです。

docker-compose.yml はそのままのこしておき、docker-compose.override.yml でカスタマイズするのに便利そうです。

公式ドキュメントにも記載がありました。

docs.docker.jp

netbox-docker の README.md の例で試してみます。

docker-compose.yml 単品の場合

nginx を抜粋すると以下の通りです。

  # nginx
  nginx:
    command: nginx -c /etc/netbox-nginx/nginx.conf
    image: nginx:1.19-alpine
    depends_on:
    - netbox
    ports:
    - 8080
    volumes:
    - netbox-static-files:/opt/netbox/netbox/static:ro
    - netbox-nginx-config:/etc/netbox-nginx/:ro

これを docker-compose up -d で起動したあと、確認します。

$ docker-compose ps
            Name                           Command               State                Ports             
--------------------------------------------------------------------------------------------------------
netbox-docker_netbox-worker_1   python3 /opt/netbox/netbox ...   Up                                     
netbox-docker_netbox_1          /opt/netbox/docker-entrypo ...   Up                                     
netbox-docker_nginx_1           /docker-entrypoint.sh ngin ...   Up      80/tcp, 0.0.0.0:49153->8080/tcp
netbox-docker_postgres_1        docker-entrypoint.sh postgres    Up      5432/tcp                       
netbox-docker_redis-cache_1     docker-entrypoint.sh sh -c ...   Up      6379/tcp                       
netbox-docker_redis_1           docker-entrypoint.sh sh -c ...   Up      6379/tcp                       

抜粋すると、以下の通り、49153 が開放されました。

netbox-docker_nginx_1           /docker-entrypoint.sh ngin ...   Up      80/tcp, 0.0.0.0:49153->8080/tcp

ただ、先程の docker-compose.yml ですと、docker-compose up のたびにポートが変わってしまい、たとえば、

netbox-docker_nginx_1           /docker-entrypoint.sh ngin ...   Up      80/tcp, 0.0.0.0:49154->8080/tcp

となってしまい不便です。

docker-compose.override.yml で上書きする

そこで docker-compose.override.yml で上書きして起動する方法を試します。

まず、以下の内容の docker-compose.override.yml を用意します。

version: '3.4'
services:
  nginx:
    ports:
      - 8000:8080
EOF

この状態で docker-compose up -d で起動したあと、確認します。

$ docker-compose ps
            Name                           Command               State                           Ports                         
-------------------------------------------------------------------------------------------------------------------------------
netbox-docker_netbox-worker_1   python3 /opt/netbox/netbox ...   Up                                                            
netbox-docker_netbox_1          /opt/netbox/docker-entrypo ...   Up                                                            
netbox-docker_nginx_1           /docker-entrypoint.sh ngin ...   Up      80/tcp, 0.0.0.0:8000->8080/tcp,0.0.0.0:49153->8080/tcp
netbox-docker_postgres_1        docker-entrypoint.sh postgres    Up      5432/tcp                                              
netbox-docker_redis-cache_1     docker-entrypoint.sh sh -c ...   Up      6379/tcp                                              
netbox-docker_redis_1           docker-entrypoint.sh sh -c ...   Up      6379/tcp  

今度は 8000 も開放されました。「も」なのでマージ的な動作なのでしょうか。

[Ansible] git config に相当する git_config モジュールを試す

はじめに

git の設定を行う git config コマンドに相当する git_config モジュールがあります。

というより、最近存在を知りました。簡単な例ですが、まとめます。

  • 動作環境
    • ansible 2.9.14

Playbook

git config --global user.email sakana@example.com
git config --global user.name sakana

に相当する Playbook です。

---
- hosts: sv
  gather_facts: false

  tasks:
    - name: git config
      git_config:
        scope: global
        name: "{{ item.name }}"
        value: "{{ item.value }}"
      loop:
        - name: user.name
          value: sakana
        - name: user.email
          value: sakana@example.com

事前確認

~/.gitconfig には何も設定がない状態からはじめます。

[admin@centos7 ~]$ cat ~/.gitconfig
cat: /home/admin/.gitconfig: No such file or directory
[admin@centos7 ~]$ git config -l
[admin@centos7 ~]$

Playbook 実行

Playbook を実行します。

$ ansible-playbook -i inventory.ini git.yml
PLAY [sv] ***************************************************************************************

TASK [git config] *******************************************************************************
changed: [sv01] => (item={'name': 'user.name', 'value': 'sakana'})
changed: [sv01] => (item={'name': 'user.email', 'value': 'sakana@example.com'})

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

事後確認

設定されたことを確認します。

[admin@centos7 ~]$ cat ~/.gitconfig
[user]
        name = sakana
        email = sakana@example.com
[admin@centos7 ~]$ git config -l
user.name=sakana
user.email=sakana@example.com
[admin@centos7 ~]$ 

おわりに

もう一度実行したら ok になってくれました。

TASK [git config] *********************************************************************
ok: [netbox01] => (item={'name': 'user.name', 'value': 'sakana'})
ok: [netbox01] => (item={'name': 'user.email', 'value': 'sakana@example.com'})

command モジュールでやってしまっても簡単に実現できるレベルですが、はやり専用モジュールがあるのは便利ですね。

[Ansible] ansible-galaxy コマンドの参照先を Automation Hub に変更する

はじめに

ansbile-galaxy コマンドは role や collection のインストールなどを行います。

デフォルトでは、Ansible Galaxyを参照します。

設定を変更することで、Automation Hub (レッドハット社提供の配布サービス) に変更できます。

ansible.tower collection のように、Ansible Galaxy にはなくAutomation Hub にあるものをインストールする場合は、設定を変更する必要があります。

この記事では手順をご紹介します。

  • 環境
    • Ansible 2.9.15

トークンの取得

ansbile-galaxy コマンドで Automation Hub を参照するにはトークンが必要です。以下の手順でトークンを取得します。

Automation Hub にログインし、左メニューの Connect to Hub をクリックします。

f:id:akira6592:20201227163506p:plain
Connect to Hub をクリック

Load Token ボタンをクリックし、表示されたトークンを控えておきます。

f:id:akira6592:20201227163611p:plain
Load Token

ansible-galaxy コマンドの設定

続いて、ansible-galaxy コマンド側の設定です。

Ansible 公式ドキュメントの Downloading a collection from Automation Hub にある通り、ansible.cfg に以下の設定を行います。

[galaxy]
server_list = automation_hub

[galaxy_server.automation_hub]
url=https://cloud.redhat.com/api/automation-hub/
auth_url=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
token=先程取得したトークンを指定

設定は以上です。

確認

確認として、Automation Hub から入手できる ansible.tower collection をインストールします。

# ansible-galaxy collection install ansible.tower
Process install dependency map
Starting collection install process
Installing 'ansible.tower:3.8.0' to '/root/.ansible/collections/ansible_collections/ansible/tower'

無事にインストールできました。

なお、Ansible Galaxy を参照する設定のまま ansible.tower collection をインストールしようとすると、見つからないので以下のエラーが発生します。

# ansible-galaxy collection install ansible.towerProcess install dependency map
ERROR! Failed to find collection ansible.tower:*

[Ansible] 「つまずき Ansible 【Part24】2020年のふりかえり」ふりかえり

はじめに

2020/12/26 に、YouTube Live で「つまずき Ansible 【Part24】2020年のふりかえり」という配信をしました。

tekunabe.connpass.com

普段は実際に作業しながら(ときには)エラーと戦って進めるシリーズです。が、今回は2020年最後ということで、今年の Ansible 生活を過去ブログ記事をもとにふりかえりました。

  • 知って便利だとおもったこと
  • びっくりしたこと
  • ハマったこと

なので、ふりかえりのふりかえりです。ほぼリンク集です。


動画

www.youtube.com

  • 0:00 イントロダクション
  • 2:35 便利だと思ったこと
  • 8:00 ハマったこと
  • 14:10 びっくりしたこと(前半)
  • 16:30 便利だと思ったこと(ansible.utils)
  • 20:08 びっくりしたこと(後半)
  • 22:37 延長線(いろいろ)
  • 35:35 おわりに


■ 知って便利だとおもったこと

モジュールのデバッグ方法

tekunabe.hatenablog.jp モジュールをコードレベルでデバッグしたいなぁとかねてより思っていました。

ansible.utils collection による複雑な構造の変数の操作

tekunabe.hatenablog.jp 複雑な構造の変数の値の更新や比較は難しいですが、この collection で結構便利にできそうです。

文字列の連結

tekunabe.hatenablog.jp

いままで、文字列の連結は + でやっていたのですが、数値を文字列として連結するときは | string によるキャストを併用していました。~ なら暗黙的にキャストしてくれて便利でした。

set_fact した値の確認

tekunabe.hatenablog.jp

一時的な確認でも debug をいちいち併用してたのですが、これは便利です。

Playbook の実行結果を JSON で取得

tekunabe.hatenablog.jp

Playbook の実行結果を切りと切り取りたいときに便利です。


■ ハマったこと

見えるはずのファイルが見えない

tekunabe.hatenablog.jp

これはもう、めちゃくちゃにハマってしまいました。

シンタックスエラーになりそうでならない

tekunabe.hatenablog.jp

シンタックスエラーにならない、という点でハマりました。


■ びっくりしたこと

Collection の本格運用

www.slideshare.net

Ansible 2.10 で、標準モジュールが減って、Collection の本格運用がはじまるという大きな変更がありました。 いくつかの仕組みのおかげで、思いの外影響は少ないようですが。

AWX 16.0.0 で画面がガラッと変わった

tekunabe.hatenablog.jp

新しい UI の AWX が来ました。まだまだ先かなと思っていたので、びっくりしました。

Ansible 3.0.0 の足音

tekunabe.hatenablog.jp

いつかは来ると思っていたのですが、Ansible 2.10 結構な変更があった矢先のできごとだったので、びっくりしました。


■ 番外編(Ansible以外)

NUC

tekunabe.hatenablog.jp

NUC を買いました。そうえばこの配信で、デモ環境と OBS(配信ソフト)を同時に動かくとPCスペックが厳しかったのが買うきっかけでした。


おわりに

今年から始めた配信「つまずき Ansible」ですが、ご覧いただいてありがとうございました。来年もマイペースでやっていきたいと思いますので、もし気になったテーマがありましたらご覧いただけると幸いです。

www.youtube.com


Part25 (来年)にむけて

以下のネタを検討中です。気が向いたものをやります。

  • Ansible 2.10 関連
  • connection: local ななにか
  • ansible.cfg
  • Jinja2、フィルター
  • Windows
  • ESXi で VM作成
  • cli_parse モジュール(Part15 の続き)

[Ansible] Ansible 実行環境としての Python とスクリプト実行環境としての Python の指定を合わせる

はじめに

ネットワークモジュールを中心に使っていると、ターゲットノードではなくコントロールノード(Ansible実行サーバー)の Python を利用することが多いです。

あくまで個人の主観ですが、Ansible 自体の実行環境としての Python (ansible_playbook_python ) と、Playbook から生成された Python スクリプトを実行する Python(ansible_python_interpreter) の境界が、あいまいになってしまうことがあります。。。

たとえば、Ansible をインストールした venv に、モジュールの実行に必要な Python モジュールをインストールしたのに「必要なパッケージがない」旨のエラーになってしまう、ということがあります。

その都度「そっか、ansible_python_interpreter に venv のパスを指定しなきゃだと気づいて、

ansible-playbook 略  -e ansible_python_interpreter=$(which python)

のようにしていました。また別の方法があったのでご紹介します。

ansible_python_interpreter 変数に ansible_playbook_python 変数を指定する

最近、以下の記事を読んで知りました。

blue-38.hatenablog.com

ansible_python_interpreter: '{{ ansible_playbook_python }}'

なるほどと思いました。

少し調べてみると、公式ドキュメントにもこの方法が載っていました。

docs.ansible.com

Be sure to set ansible_python_interpreter: “{{ ansible_playbook_python }}” in host_vars/localhost.yml, for example.

目からうろこでした。

なお、ansible_playbook_python 変数は公式ドキュメントの https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#magic-variables の一覧に掲載されています。

CML の Web UI で複数ノードを選択する3つの方法

はじめに

シスコの仮想ラボ環境 CMLでノードをいくつも配置していると、複数ノードまとめて起動や停止したいたいときがあります。

ラボ全体でしたら、それはそれで操作方法があるのですが「これとこれとこれだけ」という指定するには別の操作が必要です。

私が知ってる限りですが、3つの方法をご紹介します。

CML-P で 2.1.1 で試しましたが、たしか 2.0 でもできた気がします。

方法1: Shift 押しながら連続クリック

Shift 押しながらノードを連続でクリックすると、複数選択できます。

(普通にノードを選択すると1つずつの選択になります)

方法2: Shift 押しながら範囲選択

Shift 押しながらノードを範囲選択すると、その範囲内のノードが複数選択できます。

方法3: NODES 欄から選択

画面下の NODES 欄からチェックボックスで選択できます。ノード名や状態によるソートと併用できるが便利です。

f:id:akira6592:20201226182111p:plain
NODES 欄から選択

おわりに

お好みの方法でどうぞ。私は 方法1 のShift 押しながら連続クリック方法が今のところ一番多いです。

[Ansible] true か false か null かで返す値を変える ternary フィルター

はじめに

ternary フィルターは、対象の値が truefalse かに応じて別の値を返します。

Jinja2 の if をいれる必要はありません。

この記事では、簡単なサンプルでご紹介します。

  • 環境
    • ansible 2.9.14


truefalse

この2値で分ける方法です。

Playbook

ternary フィルターの第1引数には、フィルター対象が true の場合の値、第2引数には false の場合に返す値を指定します。

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: ternary test
      debug:
        msg: "{{ item | ternary('一致', '不一致') }}"
      loop:
        - "{{ (1 == 1) }}"  # true
        - "{{ (1 == 0) }}"  # false

実行

それぞれ、一致不一致 が表示されます。

TASK [ternary test] *************************************
ok: [localhost] => (item=true) => {
    "msg": "一致"
}
ok: [localhost] => (item=false) => {
    "msg": "不一致"
}


truefalsenull

ternary フィルターの第3引数には、フィルター対象が null の場合に返す値を指定します。

Playbook

先程の Playbook に加えて、第3引数を追加します。マッチさせるために、ループの最後に null を追加します。

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: ternary test
      debug:
        msg: "{{ item | ternary('一致', '不一致', 'nullです') }}"  # 第3引数を追加
      loop:
        - "{{ (1 == 1) }}"  # true
        - "{{ (1 == 0) }}"  # false
        - null  # null

実行

Playbook を実行します。null のときは、第3引数で指定した nullです が表示されます。

TASK [ternary test] ************************************
ok: [localhost] => (item=true) => {
    "msg": "一致"
}
ok: [localhost] => (item=false) => {
    "msg": "不一致"
}
ok: [localhost] => (item=None) => {
    "msg": "nullです"
}


まとめ

Jinja2 の if で埋め込んで同じことができるかもしれませんが、この程度であれば ternary フィルターのほうがすっきりして Ansible らしいのかなと思います。

参考

docs.ansible.com