ansibleのwin_aclで「適用先：このフォルダーのみ」を実現する方法

# はじめに

ansibleで Windows の設定をしてみた。
フォルダアクセス許可の設定でどうしてもやりたかったことができなかった。
いろいろ試してみたら、公式ドキュメントに記載されていない方法が使えた。
そんなお話です。

# 前提

## 環境

* **管理対象**
    * Windows 2012R2
* **ansible 実行元**
    * Ubuntu 20.04 LTS (Windows10proのwsl2で動作）
    * ansible 2.9.13
    * python 3.8.2

## 説明しないこと

ansibleインストール、基本的な利用方法とかは省きます。
あと「なんでそんな設定したいんだ？」も気にしない方向で。

# 本題

## やりたいこと

* 新規フォルダ作成：***T:\Share\test***
* AdministratorsとSystemにフルコントロール
* Usersに読み取りと実行権限（ただし**、適用先は「このフォルダーのみ」**）
* 親フォルダからの継承は削除

## 完成形

フォルダプロパティのセキュリティの詳細設定、または、icaclsの出力結果が図のようになったら完成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617842/d2977e01-e6b0-71f0-64e9-fbb5b2b32c31.png)

## ansibleでの実現方法

win_file, win_acl, win_acl_inheritanceで実現します。
とりあえず2日ぐらいかけて辿り着いた完成形は以下の通り。

```:hosts
[windows]
192.168.0.2

[windows:vars]
ansible_user=※ユーザ名※
ansible_password=※パスワード※
ansible_port=5986
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
```

```yaml:playbook.yml
- hosts: windows
  tasks:
    - name: フォルダ作成
      win_file:
        path: T:\Shares\test
        state: directory

    - name: 許可：フルコントロール：このフォルダー、サブフォルダ―およびファイル（Administrators, SYSTEM）
      win_acl:
        path:   T:\Shares\test
        rights: "{{ item.rights }}"
        user:   "{{ item.user }}"
        type:   allow
        # inherit のデフォルトは以下
        inherit: ObjectInherit,ContainerInherit
      with_items:
        - { rights: FullControl, user: BUILTIN\Administrators }
        - { rights: FullControl, user: SYSTEM }

    - name: 許可：読み取りと実行：このフォルダのみ（Users）
      win_acl:
        path: T:\Shares\test
        rights: "{{ item.rights }}"
        user: "{{ item.user }}"
        type: allow
        # win_aclドキュメントには明示されていないが、Noneの指定も可能
        inherit: None
      with_items:
        - { rights: ReadAndExec, user: BUILTIN\Users }

    - name: 継承無効化
      win_acl_inheritance:
        path: T:\Shares\test
        state: absent
```

```shel:実行方法
% ansible-playbook -i hosts playbook.yml
```

## win_aclで「適用先」を変更する方法

win_aclにおいて、アクセス許可エントリの「適用先」の指定は ***inherit パラメータ*** にて行います。
「[win_acl – Set file/directory/registry permissions for a system user or group](https://docs.ansible.com/ansible/latest/modules/win_acl_module.html#parameter-inherit)」に以下のように記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617842/9a055be5-4c52-fdeb-b025-52eb46e11a40.png)

実際に試してみたらこんな感じ。

| inheritの設定値 | 「適用先」の表示 |
|:--|:--|
| ObjectInherit |  このフォルダーとファイル |
| ContainerInherit |  このフォルダーとサブフォルダー |
| ContainerInherit,ObjectInherit | このフォルダー、サブフォルダーおよびファイル |
|※inheritパラメータ省略時 | このフォルダー、サブフォルダーおよびファイル<br> **（ディレクトリのデフォルトが適用される）** |


あれ？「このフォルダーのみ」が指定できないですね？

## 実は「inherit: None」が使える

まあ上のymlファイルで答え出しちゃってるわけですが。
[Commentsのリンク](https://docs.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags?redirectedfrom=MSDN&view=dotnet-plat-ext-3.1)をたどると、***ContainerInherit***, ***ObjectInherit*** に加えて
***None*** が指定できそうなので、やってみたらできたという話でした。

| inheritの設定値 | 「適用先」の表示 |
|:--|:--|
| None |  このフォルダーのみ |



# おわりに

vscodeでタスクを別ファイルにして```inherit: None```を指定すると、「そんな値は許可されていないよ」と怒られます。
実行には問題ないので構わないのですが、このエラーだけ無視するような設定はできんもんかな…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617842/ab798ffe-d402-6cfe-1ed5-dd9ff0b57355.png)

なお、win_aclは**権限追加**コマンドなので、いろいろ実験したい場合は都度フォルダ削除するといいです。
そうしないと過去の設定が重なり合って、想定した結果にならない場合があります。