てんこ

ブログ名は愛猫(てん)の愛称です。中身は個人のIT系学習記録です。

僕は計画が苦手で、克服したいと思っています。

すごく久しぶりのブログエントリです。ポエムです。

このブログは今年1月半ばから更新停止しているのですが、 仕事で忙しい…というよりも、いろいろと心がポキッと折れてしまったためです。 この投稿も、ブログ投稿再開できる一個のきっかけにできれば…

自戒のためにも、現状を書いておきます。

PMP関連

今年、1月2月と会社にお金を出してもらって、PMPの資格試験向けの研修に参加させていただきました。(2月の名古屋開催では、一般男性さんとのAnsible飯が実現できました!)

研修申し込み当時(昨年9月くらい)は割と「PM資格取って実践してやるぜー!!」と息巻いていたのですが、改めてPMBOK体系的に学ぶことで、「自身の行動に関する計画性のなさ」を身に染みて感じました。

仕事での空回り

また、並行して仕事の中でも

  • いろいろと計画をしっかり立てられていないものが破綻したり
  • フォローしてくれるいろんな人に迷惑をかけたり
  • 精神的にダメージを受けてしまったり
  • その結果でパフォーマンスが上がらない

など負のサイクルが続いていました。(今も微妙に残ってます)

目的を見失いかけたり

仕事で空回りした原因でもあり、結果でもあるところなのですが、

  • 「これって本当にやっていて意味があるのかな?」
  • 「これを進めることで、誰がどんな形で幸せになるのかな?」
  • 「もっと他に優先すべきことがあるんじゃないのかな?」

というような、自身では納得感が持てない(と思い込んでいた)仕事を突貫でやることになった結果、「自分は今後どこに向かえばいいんだろう…」という点においても迷子になりかけていました。

自身のこれまでをふりかえって

色々思い返して、以下のようなツイートをしています。

思い出してみた結果、あまり具体的な到達点をイメージしながら物事を進めるのは得意ではなく、頑張っても2週間くらいの手の届く範囲でコントロールできる仕事を繋いできた気がするなあと思い出しました。

多少長期の仕事でうまく勧められたのは、周りがいろいろと気を配ってくれたからだったなあとか。

そんなことを思い返しながら、研修申し込み当初の勢いと、現状のパフォーマンス上がらない状況を比較してしまって、毎日へこんでいる日々でございます。

今後について

仕事の目的、については、最近やっと、「ビジョンまで照らして先を見通せてなかったのが、納得感がなかった原因だな」というのがわかりまして、少しずつ前向きにとらえられるようになってきました。

今でも計画を立てるのは苦手ですが、とはいえ、その苦手を克服するために受けたPMBOK研修でもあるわけです。

それを現場で再認識できた、というのを得られた成果としてとらえ、少しずつ学習・実践していくことで苦手が克服できる!というのを直近の目標として日々精進していきたいと思います。

AnsibleでA10のvThunderをいじってみた

今回は、AnsibleでA10 NetworksさんのvThunderにおいて、ClassListを定義する操作をやってみました。

Ansibleをインストールするだけでは導入されないモジュールをインストールから試すのが初めてなので、そのあたりも書いてみたいと思います。

A10さん機器向けのもくもく会用のコンテンツはこちらで公開されています。

圧倒的感謝!

中を確認してみたら、確かにa10_protocolが必要になってたりなど、最新のモジュールの仕様に合わせたコンテンツになっていました。

Ansible関連の実践記事一覧はこちら


目的

A10Networksさんのモジュールでどんな感じの操作ができるか確認するため。

環境

  • ansible: 2.9.0
  • python: 3.6.8 (virtualenv環境配下)
  • vThunder: 4.1.1-P9 build 105

モジュール実行環境の整備

A10 Networksさんのモジュールの導入方法はこちらに、丁寧に解説頂いています。

https://github.com/kishizuka4989/ansible_training_a10_thuner_adc/blob/master/1.0-adc-primer/202001_Ansible_Guide.pdf

私は、virtualenv環境だったので、以下の流れで実施。

■ 1. virtualenvをActivate

$ source <venv_path>/bin/activate
(venv_name)$ 

■ 2. gitでa10さんのリポジトリからデータをCloneしpipでインストール

$ git clone https://github.com/a10networks/a10-ansible a10-ansible 
$ cd a10-ansible/
$ pip install -e .

■3. 環境変数を修正(導入方法の要点に記載あり)

 $ export ANSIBLE_LIBRARY="/home/ansible/a10-ansible/a10_ansible/library"

■4. ansible.cfgを修正(virtualenv環境なため、これを入れないと、エラーが発生しました)

[defaults]
()
interpreter_python=/home/ansible/p3-ansible29/bin/python3

【参考】発生するエラーの内容

TASK [Create Class] **************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: NameError: name 'module' is not defined

Playbookのリファレンス

モジュールそのもののは、Gitに公開されています。

トップページに簡単な解説がありますが、それ以外のまとまったドキュメントはモジュールの中身を見て使い方を把握する…という感じなようです。

(もしかしたら法人として相談したらリファレンスガイドみたいなPDFを頂けたりするのかしら…)

ただ、いくつかサンプルPlaybookも公開されていますので、Playbook作成そのものにはあまり困らなさそうです。

特徴

上記の公開モジュールのTOPにも記載がありますが、A10さんのモジュールは他のモジュールと少し毛色が違う感じのstateが用意されています。

state 動作 説明
present 作成/上書き いつもの
absent 削除 いつもの
noop 情報取得 指定したモジュールに関連する現状設定取得
get_type: single で指定された要素の情報を取得
get_type: list でモジュールに関連する全情報を取得
get_type: oper でステータス情報を取得?(未確認)
get_type: stats でカウンタ情報を取得?(未確認)※指定なしだとこれっぽい

試しに、適当にclasslistを設定して情報を取ってみたものはこちら。

■取得用のPlaybook

---
- hosts: vthunder
  connection: local
  gather_facts: no

  vars:
    a10_host: "{{ ansible_host }}"

  tasks:
  - name: Create Class
    a10_class_list:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"
      name: "listname"
      state: noop
      get_type: single
    register: results

  - name: debug
    debug: 
      var: results

■出力結果

TASK [debug] *********************************************************************************************************************************************
ok: [192.168.10.63] => {
    "results": {
        "changed": false,
        "failed": false,
        "message": "",
        "original_message": "",
        "result": {
            "class-list": {
                "ac-list": [
                    {
                        "ac-key-string": "office365",
                        "ac-match-type": "contains"
                    },
                    {
                        "ac-key-string": "mogemoge.com",
                        "ac-match-type": "equals"
                    }
                ],
                "file": 0,
                "name": "listname",
                "type": "ac",
                "uuid": "d6168ac6-37df-11ea-a057-000c296a0844"
            }
        }
    }
}

注意点

fortios用のモジュールの癖で、情報取得→その要素を使ってPlaybook作成、なんていう流れがあったんですが、A10さんの場合、機器から帰ってくるキーがそのままPlaybook側で使える、というわけではなさそうです。

例:ClassListのタイプ

■情報取得で得られる形式

"type": "ac",

■Playbookでの指定方法

ntype: "ac"

このあたりは一定のルールはなさそうなので、都度モジュールの上のほうを見ながら、Requireを探したりキー情報を探したりする必要がありそうです。

また、fortiosのときにもあった、ハイフンとアンダーバーの変換も実施されているようでした。(こちらも本体内部はハイフン)

作成したPlaybook

前置きが長くなりましたが、こんなPlaybookを作って、ClassListを宣言することができました。

---
- hosts: vthunder
  connection: local
  gather_facts: no

  vars:
    a10_host: "{{ ansible_host }}"

  tasks:
  - name: Create Class
    a10_class_list:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"
      name: "listname"
      ntype: "ac"
      ac_list: 
         - ac_match_type: "contains"
           ac_key_string: "office365"
         - ac_match_type: "equals"
           ac_key_string: "mogemoge.com"
      state: present
    register: results

  - name: debug
    debug: 
      var: results


  - name: Write memory
    a10_write_memory:
      a10_host: "{{ a10_host }}"
      a10_username: "{{ a10_username }}"
      a10_password: "{{ a10_password }}"
      a10_port: "{{ a10_port }}"
      a10_protocol: "{{ a10_protocol }}"      
      state: present
      partition: all     

■出力結果

TASK [debug] *********************************************************************************************************************************************
ok: [192.168.10.63] => {
    "results": {
        "changed": true,
        "class-list": {
            "ac-list": [
                {
                    "ac-key-string": "office365",
                    "ac-match-type": "contains"
                },
                {
                    "ac-key-string": "mogemoge.com",
                    "ac-match-type": "equals"
                }
            ],
            "file": 0,
            "name": "listname",
            "type": "ac",
            "uuid": "303d478a-37e8-11ea-a057-000c296a0844"
        },
        "failed": false,
        "message": "",
        "original_message": "",
        "result": {}
    }
}

TASK [Write memory] **************************************************************************************************************************************
changed: [192.168.10.63]

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

■WebUI上で作成されたものを確認

f:id:tatematsu_san:20200115224643p:plain

感想

もくもく会以外で実際に触ってみた感想として、初動こそ少し手惑いましたが、本体内でエラーになった場合でもしっかりとリターンメッセージを返してくれたりと、これまで触ってきたfortios用モジュールよりもだいぶ丁寧に作られているなあ、という印象でした。(fortiiosモジュールは、エラーコードしか返してくれないので…)

今回作成したClassListは、前回のFortiosのSSL復号除外リストと同様、HTTPアクセス系の動きをコントロールするために利用します。このリストを共通化しつつForti/A10の各々の形式に変化して投入すれば、やりたいことができそうです。

このような、機器を挟んだ情報の連動をAnsibleを中心に組み立てたいところなので、もう少しいろいろと考えながら検証してみたいと思います。

AnsibleでFortigateのSSL/SSHプロファイルを設定してみた【不具合あり】

年末に頂いていたお題がすっかり遅くなってしまい、申し訳ありません。

AnsiblejpのSlackにて、FortigateのSSLプロファイルに関するモジュールでのご相談があり、試していく中でいくつか分かったことがありますので記録しておきます。

Ansible関連の実践記事一覧はこちら


目的

FortigateのSSL/SSHプロファイルの操作に利用するモジュールの動作を確認するため

環境

※普段はhttpapiを利用していますが、ご相談いただいた際のPlaybookがfortiosapiだったので今回はこちら。

SSL/SSHプロファイルについて解説

少し長くなりますが「SSL/SSHプロファイル」についての解説はこちら

昨今、HTTPではなくHTTPSでWebサイトを公開しているケースが増えています。

HTTPS通信は途中経路が暗号化されているため、セキュリティ系の装置でその中身を見て処理をしようと思っても、暗号化されたコンテンツの中身まで読み取ることができません。

このような状況でも詳細なアクセスログを取得したり、コンテンツのスキャンを行うために、Fortigateだけではなくさまざまなセキュリティ機器で「SSL復号」という処理が行われています。

ここではSSL復号の詳細な解説はしません。参考として、PaloAlto社のサイトのリンクを張っておきます。

このSSL復号ですが、様々な状況で「復号の除外」を行う必要があります。除外が必要なケースについて、いくつか例をあげておきます。

  • クライアント証明書が必要な場合
  • カスタムCA証明書が入れられなかったり、アプリケーションがOSの証明書ストアを参照しなかったりする場合
  • プロトコル的にはHTTPSを利用しているが、HTTPSではなく、トンネリング用途で使っている場合(SSL-VPNなど)

タイトルにある、「SSLプロファイル」というのは、上記のような復号処理の条件を定義する設定箇所のFortigate上での名前です。

Fortigateの場合、SSLプロファイルは以下の3種類しかないはずです。

名前 用途 備考
certificate-inspection Webサーバのアイデンティティ確認のため 初期値・カスタム不可
custom-deep-inspection 除外で定義されたものを除いてデータを復号・再暗号化する カスタム可能
deep-inspection 全てのサイトに対してデータを復号・再暗号化する 初期値・カスタム不可

この3種類のうち、カスタム可能なのは「custom-deep-inspection」しかありません。そのため、SSL復号の除外を設定する場合には、必然的に「custom-deep-inspection」のSSLプロファイルを利用することになります。

こちらのサイトに、設定方法まで含めてまとまっていました。興味のある方はご参照ください。

AnsibleでFortigateの上記SSL/SSHプロファイルを操作する場合、「fortios_firewall_ssl_ssh_profile」モジュールを利用します。

本題

頂いた質問事項

以下のようなPlaybookを作成したが、以下のような症状が発生している。

  • 既にcustom-deep-inspectionにID1/2/3がある状態だとChangedとなるが値が変わらない
  • custom-deep-inspectionに何も登録がない状態だと、Failedとなる。
  tasks:
  - name: Configure SSL/SSH protocol options in Fortinet's FortiOS and FortiGate.
    fortios_firewall_ssl_ssh_profile:
      host: "{{ host }}"
      username: "{{ username }}"
      password: "{{ password }}"
      vdom: "{{ vdom }}"
      https: "yes"
      ssl_verify: "{{ ssl_verify }}"
      state: "present"
      firewall_ssl_ssh_profile:
        name: "custom-deep-inspection"
        ssl_exempt:
          - id: "1"
            type: "wildcard-fqdn"
            wildcard_fqdn: "test_1"
          - id: "2"
            type: "wildcard-fqdn"
            wildcard_fqdn: "test_2"
          - id: "3"
            type: "wildcard-fqdn"
            wildcard_fqdn: "test_3"

こちらで確認してみた結果

こちらでも確認してみたところ、以下のような症状が確認できました。

  • ご相談いただいた症状は再現する。
  • ID1/2/3がある状態でPlaybookでID1/2/4のリクエストを投げると以下のようになり、結果はFailedになる。
    • ID1/2はそのまま残る。(値の変更は反映されない)
    • ID3は消える。
    • ID4は作成されない。
  • ssl_exemptのリスト形式以外の箇所は正常に(?)動作する
    • commentを入れると上書きできたり(changed)
    • SSL処理対象をコントロールする構文も問題なく動作したり(changed)
    • ただし、ssl_exemptの症状を再現させてAnsibleの処理結果が「Failed」となっても、ssl_exemptの部分以外は設定が反映されてしまう。

暫定回避方法について

AnsiblejpのSlackで得られた情報によると、現在のところ、この症状を回避するためには、上記のPlaybookのうち「wildcard_fqdn」(アンダーバー)の部分を「wildcard-fqdn」(ハイフン)とする必要があるようです。

この記述方法は、「fortios_firewall_ssl_ssh_profile」モジュール のリファレンス上のexampleとは異なる記載方法となりますが、下記のように書き換えることで正常にPlaybookが動作することが確認できました。

        ssl_exempt:
          - id: "1"
            type: "wildcard-fqdn"
            wildcard-fqdn: "test_1" # ここ
          - id: "2"
            type: "wildcard-fqdn"
            wildcard-fqdn: "test_2" # ここ
          - id: "4"
            type: "wildcard-fqdn"
            wildcard-fqdn: "test_3" # ここ

f:id:tatematsu_san:20200106205301p:plain

原因について

我らがよこちさんが、fortios用モジュールのissueから原因となるものを見つけてくださいました。

要約すると、以下のような処理の不具合のようです。

  • fortiosの内部では、パラメータはハイフンで処理されている(こちらに実例を挙げてあります)
  • AnsibleのPlaybook側では、Snake Case(アンダーバー)で記載する形が想定されている
  • この間のコンバートを、「 _ → - 」に変換するファンクションで実装している
  • この変換処理が、うまく動かない場合がある【不具合箇所】

ざっと眺めている限りだと、「List形式」でパラメータを与える部分で、その要素に「_を含むパラメータ」がある場合にこの不具合が出るようです。ネスト処理の部分ですかね。

そのため、今回例に挙げたSSL/SSHプロファイル以外の箇所でも該当する部分はあるようです。(fortios_firewall_addressとか)

正式な対応方法について

どうやら、2019年の年末に修正は完了しているようです。

github.com

よこちさんも、すでに動作確認を実施頂いているようですね。さすがよこちさん!

実際のモジュールへの取り込みは、どのタイミングで実施されるんですかね。Collectionとか使うんでしょうか。

ちょっと対処方法が締まりませんが、類似の不具合が確認されたら、以下の方法をお試しいただければと思います。

  • 同様の症状が出る場合はハイフンにして試してみる
  • Ansible用のモジュールが更新されたらアンダーバーに直して試してみる

2019年をふりかえる

f:id:tatematsu_san:20191228163034p:plain

年の瀬も迫ってきたので、2019年をふりかえりたいと思います。長々とポエムってますがご容赦ください。ほぼ自分向けです。

総括

今年は自分にとって「変化の年」でした。

考え方や行動、時間の使い方に大きな変化がありました。

会社でだけでなく、プライベートまで含めていろいろと行動が変化したのを感じます。

自分にとってはとてもいい変化だと感じたため、これを今後も継続していきます。

サマリ

  • 会社内で、気が置けない同僚(ただし別部門)に出会うことができた。
  • 外に出て、異なる世界・文化・人に触れることでとても良い刺激をもらえた。
  • 本を読み、咀嚼し、実践することの大切さを実感することができた
  • 「可視化」「ふりかえり」の重要性を実感することができた。
  • アウトプットすることについて、さまざまなメリットがあることが実感できた。
  • もふもふは正義

月毎のふりかえり

1月

  • これまで社内SNSだけでの交流だった同僚と実際に会って意気投合した。
  • 上述した同僚からAnsible特集のあるSoftwareDesign2018年12月号をもらって、Ansibleの現在のカバー範囲を再認識した。

詳細はここをクリック

■同僚(A)との出会い

同僚(A)とは、別部門の所属ということもありそれまでは顔を合わせたことなかったのですが、社内SNSへの書き込みの傾向などから、似た者同士だろうなあという匂いを感じていました。そんな関係が一年くらい続いた後、2月のセミナーに一緒に行くことになったので飲み会を提案。

初対面の飲み会は、共通の知人の別の同僚(B)も含めて3人で飲んだのですが、彼(B)曰く「〇〇さんが二人いる」というくらい考え方や姿勢が似ていたそうです。

結果、今も一緒に飲みに行ったり、いろいろな情報交換をしたりするいい仲間になれました。この出会いは大きかったです。

■Ansible関連の話

Ansibleについては、2016年くらいからRedmineのインストールするときなどに触りだけ機会はあったのですが、「サーバだけならChef/Puppetと同じかなー」という印象で、仕事への効果も薄そうな印象だったため、積極的には学ぶ行動はしていませんでした。今年改めてSD12月号を読んで、NWに関しても行けそうな雰囲気を感じたため、徐々にアンテナを張るようになりました。

2月

  • 某所で開催されたRedHatさんのセミナでAnsibleをちゃんと学ぶ決心をした。
  • 同僚(A)の紹介でAnsibleもくもく会にリモートで初参加した。
  • 保護猫活動家さん主催の譲渡会で、てんこさんとMeetup(奥さんが一目惚れ)。お試し飼育の予約をした。

この2月が、いろいろな意味で人生の転機だったと思います。

詳細はここをクリック

■Ansible関連の話

RedHatさんのセミナーには同僚(A)と一緒に参加したのですが、そこでRedHatさんの重点ビジネス領域の3本柱を紹介いただき、すでに(A)がOpenShiftに取り組んでいたため、「私はAnsibleをやる」と言い切りました。

その後、少しだけSD12月号を読み進め、基礎を学ばずにいきなりAWX環境を作ったりしました。

そんな状態でAnsibleもくもく会にリモートで初参加したものの、トンチンカンな質問をしていたりして、今思い出すと顔から火が出る思いです。

にもかかわらず、Ansibleユーザ会の皆様は丁寧にQA対応いただき、「このコミュニティなら参加していけるかもしれない」と思ったのを覚えています。

■てんこ

あとは、てんこさんです。住宅展示場で開催されていた譲渡会に参加したのが出合いです。保護猫活動家さんに「猫は初めて飼う」「共働きである」という相談をしたところ、「成猫でメスの子が良い。あさひ(てんこさんの昔の名前)はぴったり」とコメントを頂き、お試し飼育の予約をしました。

3月

もくもく会のリモート参加のみです。

ちょっと仕事が忙しかったこともあり、この時期はあまり積極的な活動はできませんでした。

4月

  • Ansibleもくもく会にリモート参加した(3回目)。
  • Ansible Night in Tokyo 2019.04にリモート参加した。
  • てんこさんがきた。

詳細はここをクリック

■Ansible関連の話

地方在住ということもあり、これまで「勉強会」というものに生で参加したことがほとんどありませんでした。このとき参加したAnsible Nightでは「実際の利用者が前に出て自身の経験や思いを話す登壇・LT」というスタイルに衝撃を受けました。

企業向けのセミナーや展示会などのプレゼンも、「モノを売るための広告だよな」みたいな形で聞いていました(実際その色が強いと思います)が、やはりそこで語られるのはきれいなことが多く、苦労する部分などの泥臭い話は導入していかないとわからないものだという思い込みがありました。

Ansible Nightでは、そういった思い込みを一気に取り去ってくれ、「ああ、実際にこうやって前に立っている方たちや、現地に参加されている方たちともっと交流や意見交換がしたいな」と思うようになりました。

■てんこ

あとは、てんこさんです。「少し鼻水がとまらないんですよー」という連絡を受けてお試し飼育の開始日が伸びていましたが、ようやく4月頭にてんこさんが我が家に来てくれました。

来た当時は3日くらい、ケージのなかで一歩もうごかず、夫婦ともどもオロオロしていたのを覚えています。今ではヒエラルキーの最上位ですが。

f:id:tatematsu_san:20190907231626j:plain

↑来た当時 ↓現在

f:id:tatematsu_san:20190914123451j:plain

5月

  • Ansibleもくもく会にリモート参加した(4回目)。
  • Ansible Night in Osaka 2019.05にリモート参加した。
  • RedHat Tech Night にリモート参加した。
  • 会社の昇進試験の学習開始。(→きんしぶる期間開始)

詳細はここをクリック

■Ansible関連の話

もくもく会の参加に全く抵抗がなくなり、開催日が待ち遠しく感じていました。 このあたりの時期に、Towerまで含めてもくもく会向けのコンテンツは触りきって、「完全に理解した」状態になっていました。

Ansible Night in Osakaでは、某一般男性氏のAnsibleによるWindows自動化の熱のこもったプレゼンに圧倒されていました。

また、その際に別の方がお話しされていた、「Ansibleの「冪等性」を生かして、サーバなどインフラ管理以外の部分で活用ができないか(会議設備などなど)」というLTは、目から鱗でした。

「なるほど、Ansibleで今できることだけでなく、妄想を話すというのも面白いな」と感じました。

■Tech Night関連の話

また、同僚(A)にも誘われ、RedHat Tech Nightもリモートで参加させていただきました。(A)は現地参加したそうです。

海底ケーブルの女の下りは強烈すぎて今でも忘れられません。

皆さんが好き勝手にしゃべる形だったこともあり、また言語経験が乏しいことからも半分くらいは理解できませんでしたが、エンジニアの皆さんが楽しそうに話をされていて、RedHatに勤めてる方は、楽しんでお仕事をされていそうだなあと感じました。

■きんしぶるの話

そんななか、会社においては昇格候補者として選抜していただき、プライベートの時間はいろいろと課題に忙殺される日々が始まりました。

Anisbleの自己学習は時間を忘れて取り組む自信があったので、上記の課題を進めるために、試験が終了するまで意図的に学習を止めることにしました。

学習に関する熱を冷めさせないため、例外として、イベント系への参加だけはOKというマイルールを設定しました。

6月

実際に外に向けた行動が変わってきたのがこの月だったなあと思います。

詳細はここをクリック

Twitter/ブログの話

Twitterもブログも、アカウントは作ったものの、目的が明確でなかったためすぐに利用を停止してしまっていました。

どうせ何かしらをやっていくなら、記録も書いたりして誰かの参考になればいいな、という単純な動機から、Twitterもブログも再開することにしました。今では、もっと昔から継続していればよかったなと後悔しています。

アウトプットはいいぞ。

Interop Tokyoの話

本業がネットワーク/セキュリティ屋さんなので、Interop系のイベントにはこれまでもよく参加していたのですが、これまでは仕事のネタになる商材を探す、という直接的な視点が中心でした。

今年はAnsibleコミュニティの方と実際にお会いできるチャンス…!というところもあり、普段とは異なる気持ちも持って参加しました。

結果、一部の方とではありますが、Ansibleコミュニティの方とも実際に対面でき、ますますコミュニティへの思いが高まったのを覚えています。

■フェニックスプロジェクトの話

個別の記事にしてありますので詳細はそちらで。

この研修には、前述した同僚(A)と参加しています。

これに参加してから、これまで漠然と抱いていた組織・プロジェクトマネジメントへの不満点や改善方法のステップなどが具体的に考えられるようになってきました。非常に良い経験をさせていただきました。

■Ansible Automatesの話

実質、Ansibleコミュニティの方々と直接会えるかもしれない初の正式イベントで、すごくドキドキしながら参加しました。

エレベーター上がってすぐのところで、なかむらさんがいらっしゃったのですが、人見知りもあり声かけせずスルーしてしまったり。

たぶんこの人、あの人かな、と思いながらやっぱり確信が持てずにスルーしてしまったり。

事前によこちさんにご挨拶させていただく約束をしていたため、そこは最低限達成を…!という思いを胸に刻み、Twitter実況というのをよくわからないまま、慣れないTwitterで少しだけ参加してみたり。

帰り際には、予定通りよこちさんや、偶然一緒になった一般男性さんとご挨拶させてもらい、その勢いで、少しだけなかむらさんにもご挨拶をさせていただいたり。

このあたりから、コミュニティの方に実際に会うっていいなと心から思えるようになりました。

この当時の一つのツイートをきっかけに仲良くなれた方もいて、小さな一歩ですが、踏み出して本当に良かったと思っています。

7月

詳細はここをクリック

■Ansible Night の話

本当は、この回ではLTができないかな、と計画していました。

6月の興奮冷めやらぬ中、やはり現地でいろいろな人と交流したい、という思いが先走ったものだと、今では反省しています。当時やってたとしても、たぶん独りよがりのLTで終わっていたと思います。

結果的に、仕事の関係もあり、現地参加は断念し、リモートで参加させていただきました。

このころから、Twitter実況などは徐々に参加できるようになっていったと思います。

■「カイゼン・ジャーニー」の話

Ansible Automatesの最後の特別公演で、「カイゼン・ジャーニー」の著者の市谷さんが講演をされていました。

実はそれまで、電子書籍で購入はしていたものの、「どうせアジャイルでしょ、開発系の話だよね」と思いこんで、お恥ずかしながら積ん読している状態でした。

前述した「フェニックスプロジェクト」とAutomatesでの公演の話を受け、「あれ?これ自分の仕事でも同じことあるよな、何か役に立ちそうじゃない?」と思い、読み始めたところ大変感銘を受けました。

語彙力が乏しいため、ざっくりな感想になってしまいますが、「俺もがんばりたい!いろいろな困難があっても目的に向かって、くじけずに前に進んでいきたい!」と思うようになりました。

これまでもあまり折れることはなかったのですが、それはどちらかというと信念というよりは意地と体力に任せた乱暴なものだったように思います。チームで乗り越えるというよりも個人スキルのパワープレイで乗り越える感じだったと思います。

そのあたりについて、非常に重要な視点を与えてくれたのが、この本でした。バイブルです。

■技書博の話

実は、技書博に参加した一番の目的は、某黄色い人と会話をすることでした。

Twitterをやっていて、フェニックスプロジェクトのブログ投稿を書いたツイートをしたのですが、某黄色い人も同じ研修を受けられて、「過去回の記録」ということで引用ツイートいただいたのが黄色い人を知ったきっかけです。

黄色い人の参加されたフェニックスプロジェクトの参加記録を見ると、枠の外し方が極まっていて、一緒に参加した同僚(A)とも、「これはすごい」と感銘を受けていました。単純にあってみたい、その人が書いている本を読んでみたい、と思ったのが、技書博へ参加した一番の動機になっています。(ミッションは達成しました)

参加前日に、他の出展者の方からも「行動すること」に背中を押していただいたのも大きかったです。

結果、当日は前述した「カイゼン・ジャーニー」の影響もあり、チームビルディング系の書籍を中心に、著者の方の「実経験」が書かれた本を買いあさりました。

まだ積んでしまっているものもありますが、この時に購入した「ふりかえり読本」シリーズと「エンジニアの成長を応援する本」は今でも何度も読み返しています。

■てんこさんの話

2週間のはずがズルズルのび、このころ正式に譲渡のお話をさせていただきました。

もう今ではてんこさんがいない生活は考えられません。

f:id:tatematsu_san:20191228132044j:plain

8月

詳細はここをクリック

■Ansible もくもく会現地参加 の話

開催日程がちょうどいいタイミングだったこともあり、有休をとり私費で東京へ行き、現地参加させていただきました。

7月の無念を晴らすべく、成果共有枠として参加したり。

Ansible飯にも参加したり。

ただ、現地参加の実績は解除したものの、やはり人見知りもあり、またAnsible実績もないのでネタもなく。

我ながら無謀な挑戦をしたなあとは思いましたが、でも行動しないと何も変わらない!と思い、きんしぶる期間でも無理やりイベントには参加していました。

■テレワークデイズ浜松の話

カイゼン・ジャーニー」の直後に「仕事ごっこ」という、沢渡あまねさんの書かれた本を読んでいました。

その沢渡さんが登壇されること、もともと仕事の中でもリモートワークについての課題を持っていたため、参考になるイベントだと思いリモートで受講。

ブログに感想は書きませんでしたが、非常にいいイベントでした。沢渡さんの「テレワーク2.0」に関する考えにもとても共感できました。

■「運用設計の教科書」の話

上記の沢渡さんのTwitterをフォローしていたら、「運用設計の教科書」に関するツイートが流れてきて、「あの沢渡さんがおすすめする本だし良いのでは」と思い購入してみたところ、超神本でした。

著者の近藤誠司さんが取り組まれてきた運用に関する工夫がギュッと凝縮されており、とても勉強になる本でした。

会社では運用に関連する部門で、ITILやITSMSも活用し、運用フローなどはかなり作りこまれているの組織で働いています。

ただ、それらを策定した人たちが、「どのような思いで」「どのような工程を踏んで」作ったのか、というのは、出来上がったものを見るだけではわかりません。

この本の中では、その工程が見事に言語化されていると感じました。

プロジェクトの中で運用開始に至るまでのステップや、そこに至るまでのどの段階でどのようなことをすべきか、という、「運用に入るまでの準備をどのようにするのか」という内容が非常に具体的に書かれていました。

この本は、社内でも多くの人に布教して回りました。本当に神本だと思います。

運用設計の教科書(Amazonへのリンク)

9月

詳細はここをクリック

このあたりは、別記事もあるので、存在するものはそちらをご参照ください。

ラグビーワールドカップはとても感動しました。ジャイアントキリングをこの目で見られるとは。

IIJの勉強会については、わかりみが深すぎるとともに、バリーくんのLineスタンプが可愛すぎて即購入してしまいました。

バリーくんはいいぞ。

10月

  • きんしぶる期間が終了した。
  • Ansibleもくもく会にリモート参加した。
  • Ansible学習を進めた。WindowsUpdateをやってみた。
  • 仕事で二人だけで「ふりかえり」をはじめてみた。

詳細はここをクリック

Ansibleについて

10月第一週に昇格試験が終わり、やっときんしぶる期間が明けたため、いろいろと活動を開始しました。

10月はWindows Updateの自動化という、自身でも非常につらみを感じる運用の自動化に取り組むところからスタートしました。

あと、zakiさんとまどまぎ自動化ごっこしたのもこのころでした(笑)

「ふりかえり」について

私の所属する部門は非常に小さな組織です。

チームのメンバーがいろいろと仕事の進め方で悩んでいるのが見て取れた時期でした。業務内容的な関わりは少なめなため、直接的な課題解決への関与は難しいかな、と思い間接的な協力ができないかと考えました。

結果、ふりかえり読本などを参考にしながらデイリーでYWTを始めてみました。結果は非常に良好。デイリーのYWTを継続していた時期は非常にパフォーマンスが出ていたと思っています。

ふりかえりすごい。やっぱり前に進む力になる。小さい単位だけでなく、チームや部門全体でやりたいと思うようになりました。

11月

詳細はここをクリック

Ansibleについて

Fortigate芸人を始めた時期です。

Ansible2.9がリリースされ、Fortigate用のモジュールがネットワーク系モジュールの中でもかなりの量を占めたにも関わらず、あまり情報がないというのが取り組み始めたきっかけです。後、仕事でもちょこちょこ触るので。

参考書に書いていない、かつ公式サポートが得られる機器(モジュール)ではないという条件でもありましたが、自分の得意分野なのでカバーできると判断し、この機器を中心にAnsibleを学んでいこうと思っていろいろとチャレンジしました。

LTについて

感想は別記事でも書きましたが、本当に楽しかったです。

その後の懇親会でも参加されたコミュニティの方々と様々な話ができ、7月、8月のリベンジが果たせたと思いました。

発表自体がうまくできなかったのは心残りですので、また同じ場に立てるように頑張ります。

12月

  • JTF2019にリモートで参加した(TLと資料追ってた)
  • 会社でAnsible関連の活動を開始した。
  • Ansible のアドベントカレンダーに参加した。
  • 技書博第二回に参加した。
  • チームでの「ふりかえり」の実績を解除した。

詳細はここをクリック

JTFについて

Ansibleコミュニティの方々や、技書博でつながった方などが参加されているようなツイートがTLに流れてきて、面白そうなイベントだと思って1日中張り付いてTLを眺めていました。

次回開催されたときは、是非現地で参加したいと思いました。

会社でのAnsible関連の活動について

大した話ではなく、RedHatさんの営業さんに来ていただいて、会社として話を聞いたり、会社のメッセージングツールの中にAnsible関連のグループを作成したりしました。

これまでは個人の趣味、というレベルの活動でしたが、いろいろと会社の中にもAnsibleに関する活動をしていることを知ってもらって、もっと多くの人に興味を持ってもらおうと思ったのがきっかけです。

折角蒔いた種ですので、しっかりと育てていきたいと思います。

アドベントカレンダーの参加について

Ansibleに関するアドベントカレンダーが3つも作成され、1個目に参加するのはまだまだ…と思い、2/3にそれぞれ1個ずつ参加させていただきました。

バトンリレー形式というのは面白いものですね。

また来年はFortigateネタ以外で参加できるよう、いろいろと知見を蓄えていきたいと思います。

技書博第二回の参加について

今回ブログエントリは書きませんでしたが、技書博の第二回にも参加しています。

前回参加した際に購入して、とても面白かった本の作者さんや、ツイッターでやり取りさせていただいた方へのご挨拶、新しい分野への興味などもあり、何冊か購入させていただきました。

まだまだ積ん読になってしまっている本が多いですが、今後も技術同人誌業界は伸びていってほしいです。第三回も参加しようと思っています。

チームの「ふりかえり」の実績解除について

これまで、組織的なチーム運営は、割と受け身に回らざるを得ない状態が多かったのですが、いろいろ思うところがあり、最終日に「ふりかえり」の実施を提案。

無事Timelineで年間総括ができ、2019年にできたこと、できなかったこと、2020年にやっていくこと、タスクバランスや越境やスキルアップに関する期待などを皆で意思統一することができました。

ふりかえりを行うことで、思い込みや行き違いが無くなった感じがします。やはり、「ふりかえり」は重要ですね。

最後に

これだけ書いて一万文字弱…定期的に長文書く人は本当にすごいですね。

ここまで読んでいただける方は稀だと思いますが、今年は皆さまに本当にお世話になりました。

また来年もいろいろと前向きに活動をしていきたいと思いますので、関わる機会がございましたら、何卒よろしくお願いいたします。

AnsibleでFortigateのLB機能を使ってみた

この記事は、Ansible 3 Advent Calendar 2019の22日目の記事です。

昨日分は、よこちさんのNetBoxに関する記事でした。

Ansibleを構成管理ツールとして使う場合、特にTower/AWXを使わない場合、インベントリをAnsibleで管理するか…というのは悩ましい点ですよね。NetBoxも一つの解にできそうですね。

さて、私の分は「またFortigate」です。すみません。

Ansibleのネットワーク系の課題をやると、A10/BIG-IPさんの課題でよく例に出る「ロードバランシング機能」があります。

実は、Fortigateでもロードバランシング機能が存在します。それをAnsibleで利用するまでの流れを記載させていただきます。

Ansible関連の実践記事一覧はこちら


目的

fortigateでロードバランシング機能を使うためのPlaybookの書き方や、<your_own_value>を明らかにするため

最初に結論

  • AnsibleでFortigateのLB機能を一通り設定することができた
    • ヘルスチェックなども問題なく動作することが分かった
  • 【残課題】手動での動作確認を、assertなどで実施できるよう学習を進める

Ansible/Fortigate環境

構成図

このような感じの構成で確認を行いました

ロードバランサー的な用語でいうと、「ワンアーム構成」です。

(自宅のネットワーク環境の構成上、これ以外つらいんです。直さねば)

f:id:tatematsu_san:20191222134920p:plain

前提条件

  • Webサーバはすでに構築されている前提
    • 各々の index.htmlにはホストを示す異なるコンテンツを配備
  • Fortigateは、シングル構成、DMZのIFにIPが付与されている程度
    • 前回作成したHA環境は今回は使っていません。
  • クライアント(Ansibleホスト)はVIPで提供される「192.168.10.113」にWebアクセスする
    • FortigateがLBとして動作し、ラウンドロビンで各Webサーバにバランシングする
    • ヘルスチェックでDownを検知したサーバには振り分けをしないようにする。
    • Webサーバへ接続する際には、Fortigateのアドレスで送信元NATする。

事前確認

■Webサーバ#1へのアクセス確認
$ curl http://192.168.10.111
Web01(192.168.10.111)

■Webサーバ#2へのアクセス確認
$ curl http://192.168.10.112
Web02(192.168.10.112)

→各Webサーバにアクセスした際、明示的に異なる結果になることを確認

LB機能が動作する環境を作成する

事前の補足

Fortigateのロードバランシング機能は、WebUIのメニュー上は[Virtual Servers]という名称です。

ただ、コマンドは[vip]だったり、[Load Balancing]だったり、いろいろ変わってくるのでちょっとわかりにくいです。

NAT機能部分に[Virtual IP]とか[IP Pool]とかもあるのでお間違え無きよう。

作業の流れ

全体的な作業の流れとしては、以下のようになります。

  1. Feature SetでLoad Balancing機能(表示するか否か)を有効化する。
  2. ヘルスモニターを作成する。
  3. Virtual Serverを作成する。
  4. 作成したVirtual Serverを用いたポリシーを設定する。

なお、最初のFeature Setは、無視しても設定は可能です。

作成したPlaybook

いろいろ使ったので、結構長くなりました。 with_item構成にしたほうが恰好がいい(ヘルスチェックのところとか)とも思うんですが、どういう単位でPlaybookを再利用するかによりますかね。個人的にはわかりやすさ重視なのでべた書きでも良い派です。

構成要素ごとに簡単に説明もします。

---
- hosts: fortigate  
  gather_facts: false

  vars:
    web01_address: "192.168.10.111"
    web02_address: "192.168.10.112"
    vip_address: "192.168.10.113"
    vip_name: "Ansible_TEST_VIP"
    tcp_port: "80"
    vip_if: "dmz"
    balance_method: "round-robin"
    policy_srcintf: "{{ vip_if }}"
    policy_dstintf: "{{ vip_if }}"
    policy_service: "HTTP"

  tasks:

#1. Feature SetでLoad Balancing機能(表示するか否か)を有効化する。
  - name: Enable Loadbalance Feature Visibillity
    fortios_system_settings:
      system_settings:
        gui_load_balance: "enable"

#2. ヘルスモニターを作成する。
  - name: Create Health Monitor(PING)
    fortios_firewall_ldb_monitor:
      firewall_ldb_monitor:
        name: "PING"
        state: "present"
        type: "ping"
        interval: "10"
        retry: "3"
        timeout: "2"
        port: "0"

  - name: Create Health Monitor(TCP_80)
    fortios_firewall_ldb_monitor:
      firewall_ldb_monitor:
        name: "TCP_80"
        state: "present"
        type: "tcp"
        interval: "10"
        retry: "3"
        timeout: "2"
        port: "{{ tcp_port }}"

  - name: Create Health Monitor(HTTP_GET_80)
    fortios_firewall_ldb_monitor:
      firewall_ldb_monitor:
        name: "HTTP_GET_80"
        state: "present"
        type: "http"
        interval: "10"
        retry: "3"
        timeout: "2"
        port: "{{ tcp_port }}"
        http_get: ""
        http_match: ""

#3. Virtual Serverを作成する。
  - name: Create VIP Setting
    fortios_firewall_vip:
      firewall_vip:
        state: "present"
        arp_reply: "enable"
        name: "{{ vip_name }}"
        comment: "{{ vip_name }}"
        id: "0"
        extip: "{{ vip_address }}"
        extintf: "{{ vip_if }}"
        protocol: "tcp"
        extport: "{{ tcp_port }}"
        server_type: "http"
        ldb_method: "{{ balance_method }}"
        type: "server-load-balance"
        monitor:
          - name: "PING"
          - name: "TCP_80"
          - name: "HTTP_GET_80"
        realservers:
          - 
            id: "1"
            client_ip: ""
            ip: "{{ web01_address }}"
            port: "{{ tcp_port }}"
            status: "active"
            healthcheck: "vip"
          - 
            id: "2"
            client_ip: ""
            ip: "{{ web02_address }}"
            port: "{{ tcp_port }}"
            status: "active"
            healthcheck: "vip"

#4. 作成したVirtual Serverを用いたポリシーを設定する。
  - name: Create Firewall Policy for VIP
    fortios_firewall_policy:
      state: "present"
      firewall_policy:
        policyid: "2"
        srcintf:
          - name: "{{ policy_srcintf }}"
        dstintf:
          - name: "{{ policy_dstintf }}"
        service:
          - name: "{{ policy_service }}"
        srcaddr: 
          - name: "all"
        dstaddr: 
          - name:  "{{ vip_name }}"
        schedule: "always"
        action: "accept"
        nat: "enable"
        status: "enable"

1. Feature SetでLoad Balancing機能(表示するか否か)を有効化する。

詳細はこちら

  - name: Enable Loadbalance Feature Visibillity
    fortios_system_settings:
      system_settings:
        gui_load_balance: "enable"

WebUIで見るとこの部分です。

f:id:tatematsu_san:20191222144106p:plain

これを有効化すると、左側のメニューの[Policy & Objects]に[Virtual Servers],[Health Check]というメニューが登場します。

f:id:tatematsu_san:20191222144252p:plain

2. ヘルスモニターを作成する。

詳細はこちら

  - name: Create Health Monitor(HTTP_GET_80)
    fortios_firewall_ldb_monitor:
      firewall_ldb_monitor:
        name: "HTTP_GET_80"
        state: "present"
        type: "http"
        interval: "10"
        retry: "3"
        timeout: "2"
        port: "{{ tcp_port }}"
        http_get: ""
        http_match: ""

HTTP監視の部分を持ってきました。 fortios_firewall_ldb_monitorというモジュールを使います。モジュールのリファレンスはこちら。

所定のパスの応答(http_get)や、レスポンスのチェック(http_match)も可能なようです。

3. Virtual Serverを作成する。

詳細はこちら

  - name: Create VIP Setting
    fortios_firewall_vip:
      firewall_vip:
        state: "present"
        arp_reply: "enable"
        name: "{{ vip_name }}"
        comment: "{{ vip_name }}"
        id: "0"
        extip: "{{ vip_address }}"
        extintf: "{{ vip_if }}"
        protocol: "tcp"
        extport: "{{ tcp_port }}"
        server_type: "http"
        ldb_method: "{{ balance_method }}"
        type: "server-load-balance"

前半部分では、対象のVIPの名前やアドレス、インターフェースの定義などを行います。

fortios_firewall_vipというモジュールを使います。モジュールのリファレンスはこちら。

ldb_method という部分がロードバランシング機能の肝です。

least-session(既存コネクション数の少ないもの)、Weighted(重みづけラウンドロビン)など、他のアルゴリズムもいくつか選択できるようです。

        monitor:
          - name: "PING"
          - name: "TCP_80"
          - name: "HTTP_GET_80"
        realservers:
          - 
            id: "1"
            client_ip: ""
            ip: "{{ web01_address }}"
            port: "{{ tcp_port }}"
            status: "active"
            healthcheck: "vip"

後半に2.で作成したヘルスモニターや、バランシング対象の実サーバの情報を登録します。対象サーバの指定で、ポリシー用のオブジェクトが使えればいいんですが、利用できないようです。残念。

4. 作成したVirtual Serverを用いたポリシーを設定する。

詳細はこちら

  - name: Create Firewall Policy for VIP
    fortios_firewall_policy:
      state: "present"
      firewall_policy:
        policyid: "2"
        srcintf:
          - name: "{{ policy_srcintf }}"
        dstintf:
          - name: "{{ policy_dstintf }}"
        service:
          - name: "{{ policy_service }}"
        srcaddr: 
          - name: "all"
        dstaddr: 
          - name:  "{{ vip_name }}"
        schedule: "always"
        action: "accept"
        nat: "enable"
        status: "enable"

別の記事でも利用した、fortios_firewall_policyを利用します。ワンアーム構成なので、実態としてはsrcintf/dstintfは同じものです。dstaddrの部分に、作成したVirtual Serverを宣言します。送信元NATはここで定義しています。

動作確認

バランシング確認

Ansibleホストからcurlで確認してみたところ、問題なくバランシングされていました。

$ curl http://192.168.10.113
Web01(192.168.10.111)

$ curl http://192.168.10.113
Web02(192.168.10.112)

$ curl http://192.168.10.113
Web01(192.168.10.111)

$ curl http://192.168.10.113
Web02(192.168.10.112)

NAT確認

192.168.10.61 - - [22/Dec/2019:15:27:39 +0900] "GET / HTTP/1.1" 200 23 "-" "curl/7.29.0"

curlでアクセスしている際の送信元IPがちゃんとFortigateのアドレス(192.168.10.61)になっています。

ヘルスチェック確認(定期監視)

サーバ側のアクセスログは以下のようになっていました。

ちゃんとインターバルで定義した10秒ごとにチェックが来ています。 User-AgentがFortiOS 4.0というのがなんとも…

192.168.10.61 - - [22/Dec/2019:12:13:49 +0900] "GET / HTTP/1.0" 200 23 "-" "FortiGate (FortiOS 4.0)"
192.168.10.61 - - [22/Dec/2019:12:13:59 +0900] "GET / HTTP/1.0" 200 23 "-" "FortiGate (FortiOS 4.0)"
192.168.10.61 - - [22/Dec/2019:12:14:09 +0900] "GET / HTTP/1.0" 200 23 "-" "FortiGate (FortiOS 4.0)"

ヘルスチェック確認(ダウン時)

試しにWeb01のhttpdをダウンさせ、動作確認してみます。

$ curl http://192.168.10.113
Web02(192.168.10.112)

$ curl http://192.168.10.113
Web02(192.168.10.112)

$ curl http://192.168.10.113
Web02(192.168.10.112)

$ curl http://192.168.10.113
Web02(192.168.10.112)

ちゃんとWeb02側だけにバランシングされました。

イベントログにもこんな形でログが記録されます。(VirtualServer側には何も出ません)

f:id:tatematsu_san:20191222151147p:plain

まとめ

以下のような結果になりました。

  • AnsibleでFortigateのLB機能を一通り設定することができた
    • ヘルスチェックなども問題なく動作することが分かった
  • 【残課題】手動での動作確認を、assertなどで実施できるよう学習を進める

商用でFortigateをLBとして使うケースはあまりないかも、とも思いますが、中小規模環境で、予算が削られて個別のLBが買えない、なんていう場合には利用できるかもしれません。(性能面は要検証です)

今回は試していませんが、SSLオフロード用機器としても利用できそうです。 また、今回はIPv4のみですが、IPv6や64/46も可能なようです。

なんかAnsibleというよりFortigate機能検証みたいな形になっていますが、どなたかのお役に立てれば幸いです。

バトンリレー

前回に引き続き、今回も無事にバトンをつなぐことができました。

お次は、@atsushi586さんです。

よろしくお願いいたします!