Ansibleでサーバセットアップにかかる工数を削減しよう

#サーバ構築時の悩み
私の勤務先では、箱のまま納品された物理サーバ（Windowsがメイン）のセットアップを行い
お客様への納品を行っています。
しかしながら、一台ずつ人の手で設定を行わなくてはならず、大量のサーバをセットアップする必要がある際、
かなりの工数がかかり、人的ミスや作業者の引き継ぎ漏れによるセットアップミス等の問題が多々起こっていました。

主にセットアップを行っている項目は以下

■事前準備・納品物確認
・パラメータシート確認・更新
・納品物取り出し
・ケーブル接続
・UPS・初期設定
・BIOS言語設定
・RAID設定
・OSｲﾝｽﾄｰﾙ
・機器保守情報確認

■Windows設定
・IEｾｷｭﾘﾃｨ強化設定
・ﾘﾓｰﾄﾃﾞｽｸﾄｯﾌﾟ許可
・WindowsUpdate
・ﾊﾟｽﾜｰﾄﾞ無期限
・パスワードの複雑性無効化
・WindowsFirewall設定変更
・ファイルエクスプローラ表示変更
・MACｱﾄﾞﾚｽ確認
・IPv6無効
・IPv4設定
・ユーザUAC無効
・ﾄﾞﾗｲﾌﾞ名変更
・ディスク構成変更
・ショートカット作成（ネットワーク/PC）
・作業ログ取得
・アプリケーションインストール

多い、、、
これ以外にも、お客様の環境依存の設定（ホスト名、IPアドレスなど）を含めると
さらに設定項目は多い、、、
このままではマズイ、、と考え、以前から気になっていたAnsibleによる自動構築を試してみることにしてみました。
とりあえず今回は物理マシンを立ち上げたあと、ホスト名等のお客様の環境依存の設定を除く箇所をAnsibleで構築してみようと思います。

#実現したいこと
・作業品質の向上
・作業工数の削減
→Ansibleによる自動構築により実現

・インフラのコード化
→せっかくAnsibleを利用するならPlayBookのバージョン管理も行っていきたい！
　と思っていますが、社内ではgit等が普及していないため、ゆくゆくは導入していきたいなぁ。

#事前準備
Ansibleの理解、実行環境の構築は以下の記事を参考にさせていただきました。

[Ansibleをはじめる人に。](https://qiita.com/t_nakayama0714/items/fe55ee56d6446f67113c)

私の場合は普段業務で使用している端末に
VirtualBox+CentOSでAnsibleの実行環境を作成しました。

また、設定を行うAnsibleでのリモ―ト作業を行うために
Windowsサーバ側ではWin-RMという機能を有効にする必要があるため、
下記パワーシェルスクリプトを作成し、右クリック→「PowerShellで実行」にて
Win-RM有効化します。

```ansiwin.ps1
Invoke-WebRequest -Uri https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 -OutFile ConfigureRemotingForAnsible.ps1
Set-NetConnectionProfile -InterfaceAlias (Get-NetConnectionProfile -IPv4Connectivity Internet).InterfaceAlias -NetworkCategory Private
Get-NetConnectionProfile -IPv4Connectivity Internet
powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1
Get-Item WSMan:\localhost\Listener\*\Port
```
これで事前準備は完了です。

#PlayBook
PlayBookをAnsibleサーバの以下のディレクトリに配置しました。



```/etc/ansible
/etc/ansible
       ├─hosts
       ├─windows_setup.yml
       └─ansible.cfg
```

実行するPlayBookは以下です。
PlayBookで使用する記述方式については以下の記事が参考になります。

[YAMLとは何か？ - いつもRailsの設定ファイルで出てくるやつの正体](https://qiita.com/Yama-to/items/587544993fb62610528a)


```Windows_setup.yml
##playybook
##サーバにC:\work\ansibleフォルダ作成
##そこにバッチファイルをコピーして実行

- hosts: windows
  tasks:
   - win_file:
        path=C:\work
        state=directory

＃FireWall設定変更
   - win_command: netsh advfirewall firewall set rule name="SNMP トラップ サービス (UDP 受信)" profile=domain new enable=yes profile=domain program=%SystemRoot%\system32\snmptrap.exe
   - win_command: netsh advfirewall firewall set rule name="SNMP トラップ サービス (UDP 受信)" profile=private,public new enable=yes profile=private,public program=%SystemRoot%\system32\snmptrap.exe
   - win_command: netsh advfirewall firewall set rule name="ファイルとプリンターの共有 (エコー要求 - ICMPv4 受信)" new enable=yes
   - win_command: netsh advfirewall firewall set rule name="ファイルとプリンターの共有 (エコー要求 - ICMPv4 送信)" new enable=yes
   - win_command: wmic UserAccount where Name='Administrator' set PasswordExpires=false

#パスワードの複雑さの要件を無効化
   - win_shell: secedit /export /cfg cfg.txt
   - win_shell: (Get-Content cfg.txt) -Replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File cfg.txt

#グループポリシーの変更
   - win_shell: secedit /configure /db new.sdb /cfg cfg.txt /areas SecurityPolicy
   - win_shell: del cfg.txt
   - win_shell: gpupdate /force

   - win_regedit:
       key: '{{ item.key }}'
       value: '{{ item.value }}'
       data: '{{ item.data }}'
       datatype: '{{ item.datatype | default("dword") }}'
     with_items:

#サーバマネージャの自動起動を停止
     - key: HKLM:\SOFTWARE\Microsoft\ServerManager
       value: DoNotOpenServerManagerAtLogon
       data: 1
       datatype: dword

#デスクトップにアイコン表示（PC、ネットワーク）
     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel
       value: {20D04FE0-3AEA-1069-A2D8-08002B30309D}
       data: 0
       datatype: dword

     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel
       value: {F02C1A0D-BE21-4350-88B0-7367FC96EF3C}
       data: 0
       datatype: dword

#コントロールパネルの表示形式変更
     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer
       value: ForceClassicControlPanel
       data: 1
       datatype: dword

#ユーザー アカウント制御（UAC）無効化
     - key: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
       value: ConsentPromptBehaviorAdmin
       data: 0
       datatype: dword

     - key: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
       value: EnableLUA
       data: 1
       datatype: dword

     - key: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
       value: PromptOnSecureDesktop
       data: 0
       datatype: dword

#WindowsUpdateの無効化
     - key: HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}
       value: IsInstalled
       data: 0
       datatype: dword

     - key: HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}
       value: IsInstalled
       data: 0
       datatype: dword



フォルダ表示オプションの変更
     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
       value: FullPath
       data: 1
       datatype: dword

     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
       value: LaunchTo
       data: 1
       datatype: dword

     - key: HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced
       value: HideFileExt
       data: 0
       datatype: dword

#再起動
   - name: reboot
     win_reboot:

```
#実行結果
準備ができたら、以下のコマンドにてPlayBookを実行します。

```
# ansible-playbook -i hosts windows_update.yml
```

正常に設定変更が完了すると

```
PLAY RECAP *************************************************************************************************************************************************************************************************
172.19.1.1                  : ok=2    changed=10    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
設定変更された箇所数が「changed」に表示されます。
これでサーバの自動構築が完了です。


#最後に
他にも設定変更を行いたい箇所があればモジュールを確認してみると幸せになれます。

[Ansible公式](https://docs.ansible.com/ansible/latest/user_guide/intro_windows.html)

とりあえず、今回の構築自動化でサーバのセットアップにかかる時間を30分/1台ほど短縮することができました。
また人的ミスもなくなったため、トータルで見たらかなりの工数を削減できたと思います。
うまくAnsibleを使用することでインフラ運用者も構築者もそのメリットを享受できるなーと感じました。
今後はTeraformなどの別ツールやクラウドの勉強をしていこうと思います。