Slide 1

Slide 1 text

他作Playbookを 実行することになって 読みにくかった話 Ansible Night オンライン! 2020.06 山口大地 (@dayamaguchi1)

Slide 2

Slide 2 text

自己紹介 氏名:山口 大地( @dayamaguchi1 ) 所属会社:株式会社エイチームライフスタイル [業務]  AWS インフラ全般(最近は terraform 触ることが多い) [ その他 ]  ・ Ansible Night in Nagoya 2019.02 の登壇以来です  ・在宅勤務の間にフィットボクシングとスパイスカレーに目覚めました  ・土曜日に映画ミッドサマー ディレクターズカット版をみて心が沈んでいます

Slide 3

Slide 3 text

今日伝えたいこと ● Ansible でプログラマブルなコードを書くと複雑性が増してわかりにくい ● 想定どおり動かないケースもあるから気をつけよう

Slide 4

Slide 4 text

業務背景 ● 旧い環境を再現する必要があった ● 過去に作成された AnsiblePlaybook を利用して、環境を再現させる ● 現行環境に追随されていないので、そこの差分は個別で埋めていく(これは本発表 外の話)

Slide 5

Slide 5 text

問題が起きたコード - name: "Httpd 設定ファイルコピー(staging)" when: web.server_name_staging is defined template: src: 'vhost.d/staging.conf' dest: '/etc/httpd/conf.d/vhost.d/staging.conf' - name: "Httpd 各種ディレクトリ展開 (staging)" when: web.server_name_staging is defined set_fact: web: env: 'staging' - name: "Httpd 設定ファイルコピー(prod)" when: web.server_name_prod is defined template: src: 'vhost.d/prod.conf' dest: '/etc/httpd/conf.d/vhost.d/prod.conf' - name: "Httpd 各種ディレクトリ展開 (prod)" when: web.server_name_prod is defined set_fact: web: env: 'prod' vars: web: server_name_prod: "{{ inventory_hostname }}" server_name_staging: "{{ inventory_hostname | regex_replace('prod', 'staging') }}"

Slide 6

Slide 6 text

問題が起きたコード - name: "Httpd 設定ファイルコピー(staging)" when: web.server_name_staging is defined template: src: 'vhost.d/staging.conf' dest: '/etc/httpd/conf.d/vhost.d/staging.conf' - name: "Httpd 各種ディレクトリ展開 (staging)" when: web.server_name_staging is defined set_fact: web: env: 'staging' - name: "Httpd 設定ファイルコピー(prod)" when: web.server_name_prod is defined template: src: 'vhost.d/prod.conf' dest: '/etc/httpd/conf.d/vhost.d/prod.conf' - name: "Httpd 各種ディレクトリ展開 (prod)" when: web.server_name_prod is defined set_fact: web: env: 'prod' vars: web: server_name_prod: "{{ inventory_hostname }}" server_name_staging: "{{ inventory_hostname | regex_replace('prod', 'staging') }}" この変数(web.server_name_staging)の定 義有無で判定したいようだ stagingかprodか、環境に応じて配置する configを変えたいようだ

Slide 7

Slide 7 text

問題が起きたコード - name: "Httpd 設定ファイルコピー(staging)" when: web.server_name_staging is defined template: src: 'vhost.d/staging.conf' dest: '/etc/httpd/conf.d/vhost.d/staging.conf' - name: "Httpd 各種ディレクトリ展開 (staging)" when: web.server_name_staging is defined set_fact: web: env: 'staging' - name: "Httpd 設定ファイルコピー(prod)" when: web.server_name_prod is defined template: src: 'vhost.d/prod.conf' dest: '/etc/httpd/conf.d/vhost.d/prod.conf' - name: "Httpd 各種ディレクトリ展開 (prod)" when: web.server_name_prod is defined set_fact: web: env: 'prod' vars: web: server_name_prod: "{{ inventory_hostname }}" server_name_staging: "{{ inventory_hostname | regex_replace('prod', 'staging') }}" envの変数を定義したいようだ(なんでここで ・・・?) mainのvarsで定義されており、inventory_hostname が登録されるようだ inventory_hostnameをweb.prod.local.testに指定し た場合、以下の通りになるはず server_name_prod:web.prod.local.test server_name_staging: web.staging.local.test

Slide 8

Slide 8 text

コードを動かす前の私の考え inventory_hostname を web.prod.test.local とした場合、以下の var が有効になる server_name_prod = web.prod.local.test server_name_staging = web.staging.local.test 定義されたので、 when の条件分岐も true となる web.prod.test.local 上に prod と staging 両方の httpd config が配置されるだろう

Slide 9

Slide 9 text

実行してみたらそうならなかった TASK [web : Httpd 設定ファイルコピー (staging)] ***************************************************************************************** changed: [web.prod.test.local] => ~~~(ry~~~~ TASK [web : Httpd 各種ディレクトリ展開 (staging)] **************************************************************************************** ok: [web.prod.test.local] => {"ansible_facts": {"web": {"env": "staging"}}, "changed": false} TASK [web : Httpd 設定ファイルコピー (prod)] ******************************************************************************************** skipping: [web.prod.test.local] => ~(ry~: "Conditional result was False"} TASK [web : Httpd 各種ディレクトリ展開 (prod)] ******************************************************************************************* skipping: [web.prod.test.local] => {"changed": false, "skip_reason": "Conditional result was False"}

Slide 10

Slide 10 text

実行してみたらそうならなかった TASK [web : Httpd 設定ファイルコピー (staging)] ***************************************************************************************** changed: [web.prod.test.local] => ~~~(ry~~~~ TASK [web : Httpd 各種ディレクトリ展開 (staging)] **************************************************************************************** ok: [web.prod.test.local] => {"ansible_facts": {"web": {"env": "staging"}}, "changed": false} TASK [web : Httpd 設定ファイルコピー (prod)] ******************************************************************************************** skipping: [web.prod.test.local] => ~(ry~: "Conditional result was False"} TASK [web : Httpd 各種ディレクトリ展開 (prod)] ******************************************************************************************* skipping: [web.prod.test.local] => {"changed": false, "skip_reason": "Conditional result was False"} どうでもいい話ですが、 (ry って死語かな?と弊社チャットで話題になったら、 2020 年新卒の方から古文に片足つっこんでますとコメントいただきました

Slide 11

Slide 11 text

なんでskipされてしまうん? ● よくわからん(教えて詳しい人) ● 作業的には vars の server_name_staging をコメントアウトすることで、 httpd(prod) が実 行できた ○ set_fact で設定した env 変数が、この先の playbook の条件分岐で利用されている ○ ここが skip されると prod 用の環境構築ができない状態になる ● 期待としては変数を上書きして動的に処理させたかったのだと思われる ○ けど実行できてなかったので、正しい状態とは言えない

Slide 12

Slide 12 text

まとめ ● 変数を上書きしていく、はプログラマブルな発想 ● ansible においては条件分岐はミスの元なので、多用しない方が良さそう ○ ましてや条件分岐の先に条件分岐があると、もはやよくわからん状態に ○ 複雑性が増していくだけなので、個人的には使いたくない ○ 変数を指定したい場合は、 playbook 内で set_fact しなくても普通に vars に書けば良い

Slide 13

Slide 13 text

おわり