てくなべ (tekunabe)

ansible / network automation / 学習メモ

HashiCorp Vault によるシークレットの登録と確認を気軽に試してみた

はじめに

Software Design 2022年4月号で始まった連載「HashiCorp Vaultではじめるシークレット管理」を読んで、HashiCorp Vault(以下 Vault)に興味を持ちました。

他、HashiCorp Learn の Vualt のコンテンツも参照してみました。

あくまでお試しレベルですが、インストールからシークレットの登録、確認までやってみたことをまとめます。

インストール

ドキュメントに掲載されていた、yum コマンドによるインストールを行いました。

$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install vault

インストールできたら、バージョンの確認をします。今回はこちらです。

$ vault --version
Vault v1.10.0 (7738ec5d0d6f5bf94a809ee0f6ff0142cfa525a6)

起動・接続準備

簡易的な、開発モードでサーバーを起動します。

$ vault server -dev
==> Vault server configuration:
...(略)...
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variable:

    $ export VAULT_ADDR='http://127.0.0.1:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: dummyxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Root Token: hvs.dummyxxxxxxxxx

Development mode should NOT be used in production installations!

サーバーを起動したターミナルはそのままにして、別のターミナルを開きます。

接続の準備として、サーバーへの接続先を環境変数に設定します。

export VAULT_ADDR='http://127.0.0.1:8200'

今回は、サーバーもクライアントも同じマシンの上です。

参考 Starting the Server | Vault - HashiCorp Learn

シークレットの追加

さっそく kv シークレットエンジンを使ってシークレットを登録します。

今回は secret/mypassword 内に password の値として p@ssw0rd を登録します。

$ vault kv put secret/mypassword password=p@ssw0rd
===== Secret Path =====
secret/data/mypassword

======= Metadata =======
Key                Value
---                -----
created_time       2022-04-07T13:34:41.03484313Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

参考 Your First Secret | Vault - HashiCorp Learn

シークレットの確認

登録できたことを vault kv get で確認します。

$ vault kv get secret/mypassword
===== Secret Path =====
secret/data/mypassword

======= Metadata =======
Key                Value
---                -----
created_time       2022-04-07T13:34:41.03484313Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
password    p@ssw0rd

password の値として p@ssw0rd が登録されていることが確認できました。

参考 Your First Secret | Vault - HashiCorp Learn

おわりに

かんたんですが Vault で試したことをまとめました。おそらくまだ Vault が持っている機能のうちのほんの少しだけだと思います。

Software Design での連載の次の記事も楽しみです。

このブログととしては別途、Ansible からシークレットを呼び出す方法を書きたいと思います。

[Ansible] Ansible 3 以降のモジュール一覧のページ

はじめに

Ansible のモジュールの一覧を確認したいときは、よく公式ドキュメントを参照します。Ansible 2.9 までは、Module Indexというページがあり、さらにカテゴリごとのページに飛べます。また、All modules というページでは全モジュールの一覧が表示されます。

Ansible-base 2.10 / Ansible 3 からは、本体と一緒に管理されていたモジュールの多くがコレクションに移行した関係で、ドキュメントの構造も変わりました。

「前にあった All modules みたいにモジュール一覧のページどっかないのかな」と思ってたら、ちゃんとあることに最近気が付きました。

モジュール一覧のページ

f:id:akira6592:20220407204101p:plain:w200
Indexes of all modules and plugins > Index of all Modules
こちらです。

左メニューの [Indexes of all modules and plugins] 内の [Index of all Modules] です。 

docs.ansible.com

ここに、ansible.builtin コレクション内のモジュールの他、Ansible Community Package に同梱される様々なコレクションのモジュールがリストになっています。

2.9 までにあったカテゴリごとではなく、コレクションごとに並んでいます。

なお、ansible-core 側のドキュメントの同じページには、ansible.builtin コレクションのみ掲載されています。

docs.ansible.com

(参考) コレクションのリスト

先程はコレクション串刺しのモジュールのリストでしたが、コレクションのリストは以下のページです。この切り口のリストは 2.9 は無かったものです。

docs.ansible.com

[Ansible] スキップされたタスクの結果は is skipped でもあり is succeeded でもある

はじめに

Ansible では、タスクの実行結果を変数に保存し、その結果を後続のタスクで確認する機能があります。

docs.ansible.com

そういえばどうなんだろうシリーズといいますか、「スキップされたタスクって succeeded 扱いだっけ?」と思ったことがありました。

結果としては、is skipped でもあり is succeeded でもありました。

試した結果をまとめます。

  • 検証環境
    • ansible 5.4.0
    • ansible-core 2.12.3

Playbook

こんな Playbook で試します。

---
- hosts: localhost
  gather_facts: false

  tasks:
    # (1) 必ずスキップされるタスク
    - name: skipped task
      ansible.builtin.debug:
        msg: this task is skipped
      register: resister_skipped
      when:
        - false

    # (2) 1が skipped 扱いの場合に実行されるタスク
    - name: debug result skipped
      ansible.builtin.debug:
        msg: resister_skipped is skipped
      when:
        - resister_skipped is skipped

    # (3) 1が succeeded 扱いの場合に実行されるタスク
    - name: debug result succeeded
      ansible.builtin.debug:
        msg: resister_skipped is succeeded
      when:
        - resister_skipped is succeeded

一番確かめたいたいのは (3) のタスクです。

結果

実行結果は以下のとおりです。 is succeeded を条件にしたタスク3も実行されました。

$ ansible-playbook -i localhost, success.yml     

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

TASK [skipped task] ************************************************************************************
skipping: [localhost]

TASK [debug result skipped] ****************************************************************************
ok: [localhost] => {
    "msg": "resister_skipped is skipped"
}

TASK [debug result succeeded] **************************************************************************
ok: [localhost] => {
    "msg": "resister_skipped is succeeded"
}

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

なお resister_skipped 変数をデバッグ表示すると以下のとおりです。

    "resister_skipped": {
        "changed": false,
        "failed": false,
        "msg": "this task is skipped"
    }

私の解釈

コードでいうとこのあたりでしょうか。

github.com

failed でない場合は succeededまたは successsuccessful )のようです。

今回の場合は「正常に判断処理がされた結果、スキップできた」ことをもって succeeded なのかなと捉えています。

一方たとえば、(1) のタスクで、when に未定義の変数をした場合(確認のためにignore_errors: true も併用)はさすがに succeeded にはなりませんでした。

---
- hosts: localhost
  gather_facts: false

  tasks:
    # (1) when が異常
    - name: skipped task
      ansible.builtin.debug:
        msg: this task is skipped
      register: resister_skipped
      when:
        - hogehoge_undefined_variable
      ignore_errors: true
        
    # (2) 1が skipped 扱いの場合に実行されるタスク
    - name: debug result skipped
      ansible.builtin.debug:
        msg: resister_skipped is skipped
      when:
        - resister_skipped is skipped

    #  (3) 1がsucceeded 扱いの場合に実行されるタスク
    - name: debug result succeeded
      ansible.builtin.debug:
        msg: resister_skipped is succeeded
      when:
        - resister_skipped is succeeded

実行結果

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

TASK [skipped task] ************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'hogehoge_undefined_variable' failed. The error was: error while evaluating conditional (hogehoge_undefined_variable): 'hogehoge_undefined_variable' is undefined\n\nThe error appears to be in '/Users/akira/Documents/git/general/vagrant/nwlab/qa/success.yml': line 7, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n    # (1) when が異常\n    - name: skipped task\n      ^ here\n"}
...ignoring

TASK [debug result skipped] ****************************************************************************************
skipping: [localhost]

TASK [debug result succeeded] **************************************************************************************
skipping: [localhost]

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

[Ansible] もくもく会コンテンツのリポジトリにある資料「Ansible Best Practices」

Ansible ユーザー会では定期的にもくもく会というハンズオンイベントを開催しています。

次回は 2022/04/21 です

コンテンツは以下のリポジトリにあります。

github.com

先日見つけたのですが、Ansible Best Practicesという資料がありました。

こうかいても動くけど、こう書いたほうがいい、というようなことや、テクニックが書かれています。

良い資料だなと思ったのでリンクを共有します。

github.com

ディレクトリは以下。

github.com

[Ansible] Automation Controller 上で実行環境コンテナ内のコレクション一覧を確認する(やや力技)

はじめに

AAP 2.x になってから、Ansible の実行環境が Python の venv から、コンテナに変わりました。

コンテナの中に、利用するコレクションを仕込んでおくわけですが、Automation Controller を触ってるときに、コンテナ内のコレクション一覧を確認したいときがあります。 ターミナルの戻らずに。横着かもなんですが・・。

そんなときの力技です。

アドホック実行を利用

Automation Controller にも、CLI 同様にアドホック実行機能があります。これを応用して localhost を対象として、確認したい実行環境を選んで ansible-galaxy colleciton list を実行すればコレクションの一覧を表示できます。

まず localhost があるインベントリで localhost を選択し、コマンドの実行をクリックします。デフォルトでは、Demo Inventory の中にあります。

f:id:akira6592:20220330233354p:plain
localhost でコマンド実行

ここからアドホック実行のウィザード画面になります。

モジュールに command、引数に ansible-galaxy colleciton list を指定します。

f:id:akira6592:20220330233529p:plain
利用モジュールと引数を指定

アドホック実行だと何故か認証情報の指定が必須(ジョブテンプレートでは任意)なので、ダミー的に Demo Credential を選択します。

f:id:akira6592:20220330233636p:plain
認証情報の指定

確認画面になるので起動ボタンをクリックします。

f:id:akira6592:20220330233656p:plain
確認画面

実行結果として、コレクション一覧が表示されます。

f:id:akira6592:20220330233737p:plain
コレクション一覧の表示

もちろん、途中で選択する実行環境によって、内容が変わります。

f:id:akira6592:20220330234011p:plain
別の実行環境の場合

おまけ(ansible-navigator の場合)

ansible-navigator collectionsだとこんな表示ができます。ターミナルに戻ってこれをやるのが正攻法かなと思います。

f:id:akira6592:20220330233806p:plain
ansible-navigator によるコレクション一覧

コレクションを指定すると、所属するモジュール類が表示されます。さらに進んでいくとドキュメントに相当する情報も見れます。

f:id:akira6592:20220330233839p:plain
モジュール類の一覧

Backlog の Git 機能の課題とプルリクエスト連携機能をためした

はじめに

タスク管理ツール(SaaS)である Backlog にはGit ホスティング機能があります。

https://support-ja.backlog.com/hc/ja/categories/360002262194-Git-Subversion

プルリクエスト機能もあるため、課題と関連付けできると経緯をトレースできていいなと思いました。

プルリクエスト画面側で関連課題を手動で選択もできますが、自動で関連付ける方法がいくつかあるようでした。

試したことを簡単にまとめます。

コミットメッセージと課題の連携

コミットメッセージに課題キーを含めると、課題のコメントにコミットメッセージが書き込まれます。

公式サイトから

「コミットと課題を連携する」にチェックを入れると、コミットメッセージに課題キーを含めてコミットすることで、その課題に自動的にコメントを登録できます。

この機能はデフォルトで有効になってました。

なお、課題キーとは課題の識別子で、プロジェクトキー-連番 という形式です。例えば TE-129 というものです。URLの課題の件名の左にも表示されます。コピペにはこのボタンが便利です。

課題キーのコピペ

それでは試してみます。

現状 TE-129 という課題があるものとします。

TE-129 add sakana というメッセージでコミットします。その後 git push します。

無事に、課題 TE-129 のコメントに、コミットメッセージが書き込まれました。

コメントにコミットメッセージが書き込まれた

コミットハッシュをクリックすると差分が表示されて便利です。

差分表示

プルリクエストの件名と関連課題の連携

今度はプルリクエスト時の連携です。

実は先程、ブランチ名に課題キーを含めるという一工夫をしました(add-sakana/TE-129)。「件名」「関連課題」の連携を確かめるためです。

公式サイトから

プルリクエストブランチの名前に、Backlogの課題キーを含めておくと、その課題の件名が「件名」に表示されます

「関連課題」にその課題キーが自動で設定されます。これらの値は変更することもできます

今回は add-sakana/TE-129 のように /課題キー というブランチ名にしましたが、スラッシュには意味はありません。「課題キーを含めておくと」ということなので、他の区切り文字や、課題キーのみのブランチ名でも大丈夫だと思います。

ということで、プルリクエストを出します。

以下のように、自動で件名や関連課題が入りました。この2箇所はブランチ名に課題キーを含めたことによる動作です。

件名と関連課題の自動入力

件名がしっくり来なかったら手動で修正してしまえば良いと思います。

また、プルリクエストに関連課題を設定することで、課題側のプルリクエストが表示され、コメントとしても書き込まれます。

課題側の関連プルリクエス

プルリクエストが作成されたことのコメント

おわりに

修正の経緯を追えるようにしておけるのは、何かと便利ですね。

firewalld の Intra Zone Forwarding の機能有無やデフォルト値

はじめに

firewalld の firewall-cmd --list-all の結果で、forward という項目がある環境とない環境があることに気が付きました。forward-ports とはまた別物です。

0.9.0で導入された、Intra Zone Forwarding という機能のものによるようです。

気になったので、いくつか別途用意して表示のされ方などを確認しました。

まとめ

先にまとめです。

RHEL firewalld バージョン Intra Zone Forwarding 機能有無 Intra Zone Forwarding デフォルト設定
8.4 0.8.2 なし -
8.4 0.9.3 あり 無効
9.0 Beta 1.0.0 あり 有効

firewalld 0.8.2 on RHEL 8.4

Red Hat Enterprise Linux 8.4 を、GUIがないサーバーとしてインストールした環境です。

[admin@localhost ~]$ cat /etc/redhat-release 
Red Hat Enterprise Linux release 8.4 (Ootpa)

バージョン確認

firewalld 0.8.2 がインストールされています。

[admin@localhost ~]$ sudo dnf list --installed | grep -i firewalld
firewalld.noarch                              0.8.2-6.el8                                 @anaconda 
firewalld-filesystem.noarch                   0.8.2-6.el8                                 @anaconda 

firewall-cmd --list-all

firewall-cmd --list-all コマンドの結果は以下のとおりです。forward という項目はありません、

[admin@localhost ~]$ sudo firewall-cmd --list-all 
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

firewalld 0.9.3 on RHEL 8.4

続いて、firewalld アップグレードした環境で試します。

firewalld のアップグレード

[admin@localhost ~]$ sudo dnf upgrade firewalld
Updating Subscription Management repositories.
Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)                       33 MB/s |  39 MB     00:01    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)                          35 MB/s |  45 MB     00:01    
Dependencies resolved.
==============================================================================================================
 Package                     Architecture  Version                 Repository                            Size
==============================================================================================================
Upgrading:
 firewalld                   noarch        0.9.3-7.el8_5.1         rhel-8-for-x86_64-baseos-rpms        502 k
 firewalld-filesystem        noarch        0.9.3-7.el8_5.1         rhel-8-for-x86_64-baseos-rpms         77 k
 python3-firewall            noarch        0.9.3-7.el8_5.1         rhel-8-for-x86_64-baseos-rpms        433 k

Transaction Summary
==============================================================================================================
Upgrade  3 Packages

Total download size: 1.0 M
Is this ok [y/N]: y
...()...

バージョン確認

0.9.3 になりました。

[admin@localhost ~]$ sudo dnf list --installed | grep -i firewalld
firewalld.noarch                              0.9.3-7.el8_5.1                             @rhel-8-for-x86_64-baseos-rpms
firewalld-filesystem.noarch                   0.9.3-7.el8_5.1                             @rhel-8-for-x86_64-baseos-rpms

firewall-cmd --list-all

firewall-cmd --list-all コマンドの結果を見ると foward: no という項目が追加されました。

[admin@localhost ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

これが firewalld 0.9.0で導入された、Intra Zone Forwarding という機能のものによるようです。

この時点では、デフォルトでオフです。(Intra Zone Forwarding 説明ページから)

By default, all currently shipped zone definitions and user created zones have forward disabled.

設定を変更してみる (有効化)

firewall-cmd コマンドのヘルプを見ると、以下オプションが増えていました。

...(略)...
  --add-forward        Enable forwarding of packets between interfaces and
                       sources in a zone [P] [Z] [T]
  --remove-forward     Disable forwarding of packets between interfaces and
                       sources in a zone [P] [Z]
  --query-forward      Return whether forwarding of packets between interfaces
                       and sources has been enabled for a zone [P] [Z]
...(略)...

軽く試します。

[admin@localhost ~]$ sudo firewall-cmd --add-forward --permanent
success
[admin@localhost ~]$ sudo firewall-cmd --reload
success

変更後、firewall-cmd --list-all を見ると forward: yes になりました。

[admin@localhost ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

一応、/etc/firewalld/zones/public.xml ファイルを見ます。<forward/> がついてました。

[admin@localhost ~]$ sudo cat /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>
  <service name="cockpit"/>
  <forward/>
</zone>

設定を変更してみる (無効化)

--remove-forward で元に戻します。

[admin@localhost ~]$ sudo firewall-cmd --remove-forward --permanent
success
[admin@localhost ~]$ sudo firewall-cmd --reload
success

forward: no に戻りました。

[admin@localhost ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

/etc/firewalld/zones/public.xml からは <forward/> が消えました。

[admin@localhost ~]$ sudo cat /etc/firewalld/zones/public.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>
  <service name="cockpit"/>
</zone>

1.0.0 on RHEL 9.0 Beta

今度は別に構築した、Red Hat Enterprise Linux 9.0 Beta の環境で試します。

[admin@localhost ~]$ cat /etc/redhat-release 
Red Hat Enterprise Linux release 9.0 Beta (Plow)

バージョン確認

firewalld 1.0.0 がインストールされています。

[admin@localhost ~]$ sudo dnf list --installed | grep -i firewalld
firewalld.noarch                              1.0.0-3.el9_b                             @anaconda 
firewalld-filesystem.noarch                   1.0.0-3.el9_b                             @anaconda 

firewall-cmd --list-all

firewall-cmd --list-all コマンドの結果を確認します。

[admin@localhost ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: cockpit dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

おっと、デフォルトで forward: yes でした。

firewalld のリリースノートとたどってみると、ちょうど 1.0.0 で Intra Zone Forwarding がデフォルトで有効になったようです。

Intra-zone forwarding by default

github.com

firewalld.org

なお、微妙に別件のようですが、Red Hat Enterprise Linux 9.0 Beta のリリースノートの Networking には

Changed behavior in firewalld when transmitting packets between zones

という記載がありました。

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9-beta/html/9.0_release_notes/new-features#enhancement_networking