毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。
0. はじめに
PowerDNSでAuthorityサーバーを起動するのはできましたが、それだけではDNSサーバーとしては役に立ちません。Zoneとレコードを設定する必要があります。
curlでポチポチ入れてもいいのですが、どうせならAnsibleでYAMLファイルにより設定できた方がいいですよね。
って事で、AnsibleのPlaybookでPowerDNSのゾーンとレコードを管理してみました。
1. 前提条件
- PowerDNS Authorityサーバーが設定されている
- APIが有効になっている
- Ansibleがインストールされている
- AnsibleはLocal接続
2. PowerDNSのゾーンとレコードを管理するAnsible
まず、PowerDNSのゾーンとレコードを管理するAnsibleのRoleですが、探してみると実は多くありません。3つぐらいあるようですが、それからさらに、まだメンテナンスされているものとなると1つだけでした。
以下のAnsible Collectionです。
kpfleming/ansible-powerdns-auth: Ansible modules which manage content in a PowerDNS Authoritative server.
現状では一番メンテナンスが継続しているものです。
こちらはAnsibleのRoleではなくて、Collectionとなっています(違いはよく分かっていません)
3. kpfleming.powerdns_authのインストール
AnsibleのCollectionとなっているので、インストールも簡単です。
3-1. Ansibleなどのインストール
事前にAnsible等の以下をインストールしておきましょう。
sudo apt update
sudo apt install -y ansible jq curl python3-pip
3-2. Ansible Galaxyでkpfleming.powerdns_auth
をインストール
requirements.ymlを作成します。
collections:
# Install a collection from Ansible Galaxy.
- name: kpfleming.powerdns_auth
以下のコマンドでインストールします。
ansible-galaxy collection install -r requirements.yml
3-3. インベントリーファイルを用意する
今回はlocalhostに接続するだけなので、インベントリーファイルも簡単です。
[localhost]
127.0.0.1
3-3. Zone設定ファイルを用意する
以下のようなZone設定ファイルを用意します。
api_keyは、PowerDNSのAPI接続時に利用するAPIのシークレットです。
皆様の環境に合わせてください。
api_urlは、API接続のURLです。ローカルになっていますがリモートの場合は正しいURLを指定してください。
gather_facts: true
にするとエラーになるので、falseにしてあります。
- hosts: localhost
name: PowerDNS
connection: local
gather_facts: false
vars:
ansible_python_interpreter: python3
pdns_version: "{{ lookup('ansible.builtin.env', 'pdns_version') }}"
common_args: &common
api_key: password
api_url: http://localhost:8081
tasks:
- name: manage dependencies needed for powerdns_auth modules
ansible.builtin.pip:
name:
- bravado
- jsonschema<4
- swagger-spec-validator==2.6.0
- name: delete zone example.com
kpfleming.powerdns_auth.zone:
<<: *common
name: example.com.
state: absent
- name: create zone example.com
kpfleming.powerdns_auth.zone:
<<: *common
name: example.com.
state: present
properties:
kind: 'Master'
nameservers:
- 'ns1.example.com.'
- 'ns2.example.com.'
soa:
mname: 'localhost.'
rname: 'hostmaster.localhost.'
rrsets:
- name: www.example.com.
type: A
ttl: 900
records:
- content: 192.0.2.1
- name: mail.example.com.
type: A
ttl: 900
records:
- content: 192.0.2.3
- content: 192.0.2.4
3-4. playbook-manage_zone.yml
ファイルの内容の解説
vars: は各種変数を宣言しています。
tasks: には3つタスクがあります。
- name: manage dependencies needed for powerdns_auth modules
- name: delete zone example.com
- name: create zone example.com
1つ目は、このCollectionを実行するため必要なPythonのパッケージをインストールしています。1回実行したらインストールされるでしょう。
2つ目は、Zoneを削除します。
3つ目は、Zoneを作成します。
2つ目のZoneの削除について説明します。
Ansibleは冪等性を確保する事ができるスクリプトです。このコレクションは既にZoneが存在すると設定を行わないようになっています。
例えば、Zoneを1回作成した後に、Aレコードを追加したいとします。
このスクリプトで1回実行したZoneファイルにAレコードを追加して、再度Ansibleを実行しても、既に設定されているZoneにレコードを追加するようにできていません。
つまり、冪等性チェックはZoneがあるかないか
までしかチェックしておらず、
レコードがあるかないか
はチェックしていません。
となると、このPlaybookは1回しか実行できないということになります。
それでは困るので、Zoneを追加する前にZoneを削除しています。
(冪等性チェックがレコード単位になると便利なのですが...)
4. 実行する
Ansible Playbookコマンドを実行します。
ansible-playbook -i hosts ./playbook-manage_zone.yml
5. まとめ
ちょっと微妙なところはありますが、ひとまず動かす事はできるようになりました。