Ansible で Fortigate のポリシーを追加・変更する

# 1. Ansible のFortiOS対応
Ansible 2.3 で、FortiOSに対応した以下2つのモジュールが導入されました。

 - [fortios_config](https://docs.ansible.com/ansible/fortios_config_module.html): コンフィグのバックアップを取得したりファイルからコンフィグを投入する
 - [fortios_ipv4_policy](https://docs.ansible.com/ansible/fortios_ipv4_policy_module.html): IPv4ポリシーを管理する

今回は `fortios_ipv4_policy` を利用して、Fortigate のコンフィグのバックアップを取得してみます。
([forios_config についてはこちら](http://qiita.com/akira6592/items/e8bd06a10d5d7462bf7f))

# 2. インストール ~ 3. インベントリファイルの作成
Ansible、pyFG インストール、インベントリファイルの作成は以下の記事を参照してください。

- [Ansible で Fortigate のコンフィグを取得する](http://qiita.com/akira6592/items/e8bd06a10d5d7462bf7f)
  - [2. インストール](http://qiita.com/akira6592/items/e8bd06a10d5d7462bf7f#2-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

  - [3. インベントリファイルの作成](http://qiita.com/akira6592/items/e8bd06a10d5d7462bf7f#3-%E3%82%A4%E3%83%B3%E3%83%99%E3%83%B3%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90)

# 4. Playbookの作成
以下のファイルを forti_policy.yml として作成します。

```yaml:Playbook(サービス2個バージョン)
---
- hosts: forti
  gather_facts: no
  connection: local

  tasks:
    - name: manage policy
      fortios_ipv4_policy:
        host: "{{ inventory_hostname }}"
        username: "{{ ansible_user }}"
        password: "{{ ansible_password }}"
        id: 1
        src_addr: internal1
        dst_addr: all
        services:
          - HTTP
          - HTTPS
        state: present
        policy_action: accept
```

# 5. 動作確認
## 5.1. ポリシー追加
### 5.1.1 事前確認
明示的なポリシーが何もない状態から始めます。

```text:コンフィグ事前確認
fortigate01 # show firewall policy
config firewall policy
end

fortigate01 #
```

### 5.1.2 Playbook実行

```text:実行
[root@localhost ansible]# ansible-playbook forti_policy.yml

PLAY [forti] *************************************************************************************************

TASK [manage policy] *****************************************************************************************
changed: [192.168.0.254]

PLAY RECAP ***************************************************************************************************
192.168.0.254               : ok=1    changed=1    unreachable=0    failed=0
```

### 5.1.3 コンフィグ確認

ポリシーが追加されました。

```text:コンフィグ事後確認
fortigate01 # show firewall policy
config firewall policy
    edit 1
        set srcintf "internal1"
        set dstintf "wan1"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "HTTP" "HTTPS"
    next
end
```

## 5.2 ポリシー変更
ここで、既存ポリシーにサービスを追加することにします。

### 5.2.1. Playbook変更
サービスの指定のところに `DNS` を追加します。

```yaml:Playbook（サービス3個バージョン）
---
- hosts: forti
  gather_facts: no
  connection: local

  tasks:
    - name: manage policy
      fortios_ipv4_policy:
        host: "{{ inventory_hostname }}"
        username: "{{ ansible_user }}"
        password: "{{ ansible_password }}"
        id: 1
        src_intf: internal1
        src_addr: all
        dst_intf: wan1
        dst_addr: all
        services:
          - HTTP
          - HTTPS
          - DNS    ######### ここ追加
        state: present
        policy_action: accept
```

5.2.3 Playbook再実行

Playbookを変更したところで、もう一度実行します。

```text:実行
[root@localhost ansible]# ansible-playbook forti_policy.yml

PLAY [forti] *************************************************************************************************

TASK [manage policy] *****************************************************************************************
changed: [192.168.0.254]

PLAY RECAP ***************************************************************************************************
192.168.0.254               : ok=1    changed=1    unreachable=0    failed=0

[root@localhost ansible]#
```

5.2.4 コンフィグ確認

`DNS` が追加され、`set service "HTTP" "HTTPS" "DNS"` となりました。

```text:コンフィグ事後確認
fortigate01 # show firewall policy
config firewall policy
    edit 1
        set srcintf "internal1"
        set dstintf "wan1"
        set srcaddr "all"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "HTTP" "HTTPS" "DNS"
    next
end

```

# 5.3 べき等性の確認

このモジュールにもべき等性があるのかどうか、確認します。

# 5.3.1 Playbook再実行

Playbookの内容は特に変更せずに、もう一度実行してみます。

```text:実行
[root@localhost ansible]# ansible-playbook forti.yml

PLAY [forti] *************************************************************************************************

TASK [manage policy] *****************************************************************************************
ok: [192.168.0.254]

PLAY RECAP ***************************************************************************************************
192.168.0.254               : ok=1    changed=0    unreachable=0    failed=0

```

`changed=0` という結果から分かるように、コンフィグは変更されませんでした。（べき等性がある）