IISにWebサイトを追加するplaybookサンプル(Ansible for Windows)

Docker for Windowsで構築したAnsibleを使ってWindows Server 2016に新しいWebサイトを追加してみます。

前準備は以下の記事にまとめました。
[Windows10 に ゼロから Ansible をインストールする](https://qiita.com/Tkm_Kit/items/58e1fb7990387a2e9c76)
[WindowsServerをAnsibleでリモート管理するための第一歩](https://qiita.com/Tkm_Kit/items/976587a086a08a0c613a)

## 設定内容
今回設定を試みるのはこちらの内容です。
1. Webサイト用リソースフォルダ作成とリソースファイルコピー
2. Webサイト用IPアドレスの新規追加
3. Webサイト用新アプリケーションプールの追加と実行ユーザーの設定
4. Webサイトの新規追加とログファイルの設定
5. Webサイト内に仮想アプリケーションの設定
6. Webサイトにhttps設定


Webサイトを設置するWindowsServer2016の環境は以下のようになっています。
- Windows Server 2016 Std.
- PowerShell 5.1
- ActiveDirectory ドメインに属する
- ホスト名w16srv, IPアドレス192.168.0.2
- [Ansible用スクリプト実行済](https://qiita.com/Tkm_Kit/items/976587a086a08a0c613a)
- IIS10インストール済

## playbookの準備

Ansible管理ホストで実行するTask定義ファイル、いわゆるplaybookを用意します。
Ansibleホストには「/mydata」としてアクセスできるWindowsフォルダ「D:\Projects\SRE\MyData」をマウントしています。
このフォルダに「tasks」と「deploy」という２つのフォルダを用意しました。

- hosts     [インベントリファイル](https://qiita.com/Tkm_Kit/items/976587a086a08a0c613a)
- tasks\\ 　　Ansibleのタスクを定義したYAMLファイル、いわゆるplaybookのストア場所
- deploy\\ 　 Webサイトの設置に必要なリソースフォルダ
    - MyWeb\\     Web用リソースファイル
        - wwwroot\\     ドキュメントルート
        - webapp\\       仮想Webアプリケーションリソースフォルダ
        - LogFiles\\     IISログの保存フォルダ
    - cert\\
        - MyWeb.pfx サーバー証明書

### 1. Webサイト用リソースフォルダ作成とリソースファイルコピー
w16srvにフォルダ「D:\Projects\MyWeb」を作りACLを設定したのち、Webサイトファイルをコピーします。

```yaml:file.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: create a new directory 'MyWeb'  # 新規ディレクトリを作成します
      win_file:
        path: D:\Projects\MyWeb
        state: directory
   
    - name: add specific AD user to execute webappsand allow rights # 作成したディレクトリにアクセス権を追加
      win_acl:
        path: D:\Projects\MyWeb
        user: domain\myweb_usr　# ユーザー名
        rights: ReadAndExecute # 権限（読み取りと実行）
        type: allow
        state: present
        inherit: ContainerInherit, ObjectInherit　# 継承可

    - name: copy web files # Ansible管理ホストからリモートサーバーへファイルをコピー
      win_copy:
        src: /mydata/deploy/MyWeb/
        dest: D:\Projects\MyWeb
```
※Windows側でymlファイルを作成する場合は、
文字コード:UTF-8
改行コード：LF
で保存しましょう。

### 2. Webサイト用IPアドレスの新規追加
w16srvのネットワークアダプタ#2にMyWeb用のIPアドレス「192.168.0.3」を追加します。

Ansibleのwindows moduleにはIPアドレス制御のmoduleはまだないようです。今回はこの設定をwin_commandモジュールを使って、PoweShellコマンドを直接呼び出すことで実現しました。しかし、この方法は「[冪等性(べきとうせい)](https://ja.wikipedia.org/wiki/%E5%86%AA%E7%AD%89)」の概念から鑑みるとよい方法ではないかもしれません。

```yaml:net.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: add IP address 192.168.0.3 on Interface #2
      win_command: powershell.exe -
      args:
        stdin: New-NetIPAddress -InterfaceIndex 2 -IPAddress "192.168.0.3" -AddressFamily IPv4 -PrefixLength 24
      register: result

    - name: debug result var # 確認のため結果を表示
      debug: var=result
```

### 3. Webサイト用新アプリケーションプールの追加と実行ユーザーの設定
w16svrのIISに新しいアプリケーションプール「MyWebAppPool」を追加します。またワーカープロセスの実行ユーザーを「domain\myweb_usr」に指定します。

```yaml:apppool.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: create a new application pool 'MyWebAppPool' # 新しいAppPoolを作成して開始
      win_iis_webapppool:
        name: MyWebAppPool
        state: started

    - name: change application pool attributes # ワーカープロセスの実行ユーザーを「domain\myweb_usr」に変更
      win_iis_webapppool:
        name: MyWebAppPool
        attributes:
          managedRuntimeVersion: v4.0
          autoStart: yes
          startMode: AlwaysRunning
          processModel.identityType: SpecificUser
          processModel.userName: domain\myweb_usr
          processModel.password: ***********
          processModel.loadUserProfile: False

```

### 4. Webサイトの新規追加とログファイルの設定
IISにWebサイト「MyWeb」をサイトID「10」で追加します。同時に「www.myweb.jp:80」バインド設定も追加します。ログ設定も変更しています。

```yaml:website.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: create a new web site 'MyWeb' 
      win_iis_website:
        name: MyWeb
        site_id: 10
        state: started
        port: 80
        ip: 192.168.0.3
        hostname: www.myweb.jp
        application_pool: MyWebAppPool
        physical_path: D:\Projects\MyWeb\wwwroot
        parameters: 
           logfile.directory:D:\Projects\MyWeb\LogFiles|logfile.logExtFileFlags:Date, Time, ClientIP, UserName, ServerIP, Method, UriStem, UriQuery, HttpStatus, Win32Status, BytesSent, BytesRecv, TimeTaken, ServerPort, UserAgent, Referer, HttpSubStatus　# ログ設定の変更
      register: website
      
    - name: debug result var # 確認のため結果を表示
      debug: var=website
```
'parameters:'でログの保存フォルダ(logfile.directory)と取得項目(logfile.logExtFileFlags)の２つの属性を変更しています。複数の属性を設定するには上記例のように「|」で連結して記述します
どのような属性が設定できるかは「applicationHost.config」を確認するとよいでしょう。

### 5. Webサイト内に仮想アプリケーションの設定
Webサイト「MyWeb」内に「/vapp」という仮想アプリケーションを追加します。

```yaml:webapp.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: add new webapplication '/vapp'
      win_iis_webapplication:
        name: /vapp
        site: MyWeb
        application_pool: MyWebAppPool
        state: present
        physical_path: D:\Projects\MyWeb\webapp　# リソースパス
```

### 6. Webサイトにhttps設定
最後にサーバー証明書「MyWeb.pfx」をインストールしてhttpsの設定を行います。
サーバー証明書「MyWeb.pfx」はAnsibleホストのdeployフォルダからリモートサーバー「D:\Setup\」へコピーし、インポート完了後削除します。

```yaml:https.yml
- hosts: w16srv
  gather_facts: no
  tasks: 
    - name: copy pfx file 'MyWeb.pfx'　# pfxファイルのコピー
      win_copy:
        src: /mydata/deploy/cert/MyWeb.pfx
        dest: D:\Setup\

    - name: import pfx certificate that is password protected　# pfxファイルのインポート（パスワード指定）
      win_certificate_store:
        path: D:\Setup\MyWeb.pfx
        state: present
        password: *************
      register: certificate　# 結果を保存

    - name: debug result var　# 確認のため結果を表示
      debug: var=certificate

    - name: add a HTTPS binding  # httpsの設定
      win_iis_webbinding:
        name: MyWeb
        protocol: https
        port: 443
        ip: 192.168.0.3
        certificate_hash: "{{ certificate.thumbprints.0 }}"　# インポートした証明書の拇印を指定
        state: present

    - name: delete imported pfx file # pfxファイルの削除
      win_shell: del D:\Setup\MyWeb.pfx

```

## playbookのチェックと実行

Ansibleホストに接続し、上記playbookを実行します。playbookを実際に実行する前に「--check」オプションをけてチェックすることをお勧めします。

```
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/file.yml --check
PLAY [w16srv] **********************************************************************
TASK [create a new directory 'MyWeb'] **********************************************
changed: [192.168.0.2]
TASK [Add specific AD user to execute webapps and allow rights] ********************
skipping: [192.168.0.2]
TASK [Copy web files] **************************************************************
changed: [192.168.0.2]
PLAY RECAP *************************************************************************
192.168.0.2             : ok=4    changed=4    unreachable=0    failed=0
```

上記のようにすべてのTASKのチェック結果でfailedがないことを確認してから、--checkなしでplaybookを実行します。
※設定内容によってはcheck時にエラーが表示される場合があります。例えばcheck時にはまだ存在しないアプリケーションプールの属性を変更しようとした場合など。

```
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/file.yml
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/net.yml
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/apppool.yml
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/website.yml
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/webapp.yml
[root@mydata]# ansible-playbook -i /mydata/hosts /mydata/tasks/https.yml
```



なお、[AnsibleのWindowsモジュールの一覧はこちらの公式ドキュメント](https://docs.ansible.com/ansible/latest/modules/list_of_windows_modules.html#windows-modules)にまとめられています。一度目を通してみるとどんなことができるかわかりますね。