Windows Subsystem for Linux(WSL)にAnsibleをインストールしてWindows10と接続する

Windows10にFall Creators Updateをインストールして、WindowsストアからUbuntsuをインストールしたので、Ansibleを入れて、Windows10を操作してみようと思い試してみました。

# WSLでの作業
http://docs.ansible.com/ansible/latest/intro_windows.html
こちらの手順を参考にAnsibleをインストールしました。

WSLではrootパスワードが不明なのでsudoでインストールしていきます。
パスワードはUbuntuインストール時に指定したものです。

```
sudo apt-get update
sudo apt-get install python-pip git libffi-dev libssl-dev -y
pip install ansible pywinrm
source ~/.profile
```

## バージョンの確認
```
username@HOST:~$ ansible --version
ansible 2.4.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/username/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/username/.local/lib/python2.7/site-packages/ansible
  executable location = /home/username/.local/bin/ansible
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
```

# 操作されるWindows10での作業

## AnsibleからWinRMで接続を受け付けるスクリプトを実行

Ansible公式のスクリプトをPowerShellで実行します。
https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
こちらをローカルにDLして、PowerShellコンソールを管理者として開きます。

```
Set-ExecutionPolicy RemoteSigned -Force
PS D:\>.\ConfigureRemotingForAnsible.ps1
```
OKが出れば完了です。

## WinRMの接続にHTTPを使用する事を許可します
デフォルトではHTTPSしか許可されていないので、HTTPを使えるようにします。

```
PS C:\WINDOWS\system32> winrm set winrm/config/service '@{AllowUnencrypted="true"}'
Service
    RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
    MaxConcurrentOperations = 4294967295
    MaxConcurrentOperationsPerUser = 1500
    EnumerationTimeoutms = 240000
    MaxConnections = 300
    MaxPacketRetrievalTimeSeconds = 120
    AllowUnencrypted = true
    Auth
        Basic = true
        Kerberos = true
        Negotiate = true
        Certificate = false
        CredSSP = false
        CbtHardeningLevel = Relaxed
    DefaultPorts
        HTTP = 5985
        HTTPS = 5986
    IPv4Filter = *
    IPv6Filter = *
    EnableCompatibilityHttpListener = false
    EnableCompatibilityHttpsListener = false
    CertificateThumbprint
    AllowRemoteAccess = true
```

### エラーが出た場合
Docker For Windowsなどをインストールしていてこんなエラーが出た場合は、一時的にアダプター自体を無効にすれば回避できます。

```
PS C:\WINDOWS\system32> winrm set winrm/config/service '@{AllowUnencrypted="true"}'
WSManFault
    Message
        ProviderFault
            WSManFault
                Message = このコンピューターのネットワーク接続の種類の 1 つが Public に設定されているため、WinRM ファイアウォール例外は機能しません。 ネットワーク接続の種類を Domain または Private に変更して、やり直してください。

エラー番号:  -2144108183 0x80338169
このコンピューターのネットワーク接続の種類の 1 つが Public に設定されているため、WinRM ファイアウォール例外は機能しません。 ネットワーク接続の 種類を Domain または Private に変更して、やり直してください。
```

#### ネットワークを無効にする方法
ネットワークと共有センターを開き、パブリックネットワーク欄に表示されているネットワークアダプタを一時的に無効にします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116259/7538393d-b39f-0325-a6aa-a9210651b242.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/116259/e8994f65-cf68-438b-d24b-bd92984741d6.png)


### 外部から接続可能か確認
外部からWinRMで接続を受け付けているポートを確認します。
HTTPがあればOKです。

```
PS C:\WINDOWS\system32> winrm enumerate winrm/config/listener
Listener
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = ~~~

Listener
    Address = *
    Transport = HTTPS
    Port = 5986
    Hostname = HOST
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = 1F9DA18E3B0F74D82ACBDE4188FC5276F238B369
    ListeningOn = ~~~
```

# WSLから自ホスト(Windows10)への接続
## 設定ファイルの作成
WSLのhomeディレクトリなどでイベントリファイル(hosts)を作成します。

```
xxxx@HOST:~$ pwd
/home/username

username@HOST:~$ vi hosts
```

イベントリファイルはこんな感じで記述します。

```vim:hosts
[windows]
192.168.xxx.xxx　⇒　自ホスト(Windows10)のIPアドレス

[windows:vars]
absible_user=Windows10のログインユーザ名
ansible_password=Windows10のログインパスワード
ansible_port=5985
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
```

## Ansibleから自ホスト(Windows10)への接続を確認
自分の環境では「-u」オプションを付けないとこんなエラーが出てしまい、結構ハマった。

```
username@HOST:~$ ansible windows -i hosts -m win_ping
192.168.xxx.xxx | UNREACHABLE! => {
    "changed": false,
    "msg": "plaintext: auth method plaintext requires a username",
    "unreachable": true
}
```

以下のように「-u」オプションを付けてやれば成功しました。

```
username@HOST:~$ ansible windows -i hosts -m win_ping -u ansible_userと同じユーザ名
192.168.xxx.xxx | SUCCESS => {
    "changed": false,
    "failed": false,
    "ping": "pong"
}
```