はじめに
AnsibleにおけるWindows用標準モジュールは充実してきたもののまだ以下の問題があります(と思っています)。
- 標準モジュールでは対応できない設定がある
- ごくまれに冪等性が担保されていないことがある
そこで、Windowsの自作モジュールを作ることにしました。
ところが調べてみてもWindowsのモジュール作成に関してはあまり見つけられなかったのでまとめることにしました。
とりあえず作れるようになる、程度の知識なので間違い等あれば是非ご指摘いただければ・・・。
Windowsモジュールとして必要な記述(おまじない的な)
標準モジュールを見てみると大体書いてあるのが次の3行です。
#!powershell
# WANT_JSON
# POWERSHELL_COMMON
こいつがあるとどうやらWindowsモジュールとして動くらしい。
これについてはここに書いてあります。
Ansible - Windows Support - Developers: Supported modules and how it works
pythonで書く場合のモジュール読み込みのようなものと思っています。
引数を受け取る
以下のようにすることでPlaybookに記述したパラメータをPowershellで受け取ることができます。
$params = Parse-Args $args
$result = @{
"changed" = $false
}
$state = Get-AnsibleParam `
-obj $params `
-name "state" `
-default "enable" `
-validateset "enable","disable" `
-resultobj $result `
-failifempty $false
Parse-ArgsやGet-AnsibleParamは ansible/module_utils/powershell.ps1
で定義されています。
ざっくりと紹介します。
Parse-Args:
- 受け取ったJSONをオブジェクトに変換する
- 引数は以下の2つ
- arguments
- supports_check_mode: default = $false なので明示的に指定しないとcheck_mode時にコケる
Get-AnsibleParam:
- オブジェクトの中から変数を引っ張り出す
- 引数は以下の8つ
- obj
- name: 抜き出す変数名
- default: パラメータが空の場合に変数に格納する値
- resultobj: モジュール終了時に返すためのJSONオブジェクト
failifempty = $true のときは必須
- failifempty: パラメータが空の場合にFAILするかどうか
defaultを指定しているときは false にしておかないと意味がない
pythonのAnsibleModuleにおける "required"
- emptyattributefailmessage: パラメータが空の場合にエラーとして返すメッセージ
あえて定義したい場合に利用する
- ValidateSet: 利用可能な値を固定したい場合に利用
複数指定する場合は , で区切る
pythonのAnsibleModuleにおける "choices"
- ValidateSetErrorMessage: ValidateSetで指定されていないパラメータを受け取った場合に
エラーとして返すメッセージ
あえて定義したい場合に利用する
モジュールを終了させる
Ansibleにおけるモジュールの終了パターンは次の3つ。
Exit-Json、Fail-Jsonのどちらも ansible/module_utils/powershell.ps1
で定義されています。
1. OK
$result = @{
"changed" = $false
}
Exit-Json $result
OKの場合は "changed" = $false
のままExit-Jsonに放り込みます。
2. Changed
$result = @{
"changed" = $false
}
$result.changed = $true
Exit-Json $result
Changedの場合は "changed" = $true
でExit-Jsonに放り込みます。
3. Failed
$result = @{
"changed" = $false
}
Fail-Json $result "Error!!"
Failedの場合はFail-Jsonに放り込みます。
引数はどちらも無くても動作しますが、メッセージ(第二引数)は表示したほうが良いかと思われます。
動作確認モジュールを作ってみよう
これまでの内容を踏まえて3パターンの終了が確認できるモジュールを作ってみます。
#!powershell
# WANT_JSON
# POWERSHELL_COMMON
$params = Parse-Args $args
$result = @{
"changed" = $false
}
$state = Get-AnsibleParam `
-obj $params `
-name "state" `
-default "ok" `
-validateset "ok","changed","failed" `
-resultobj $result `
-failifempty $false
switch ($state) {
"ok" {
Exit-Json $result
}
"changed" {
$result.changed = $true
Exit-Json $result
}
"failed" {
Fail-Json $result "[Error] state is failed!!"
}
}
実行結果はこんな感じです。
# ansible -i inventory -m test win-test
win-test | SUCCESS => {
"changed": false
}
# ansible -i inventory -m test -a "state=ok" win-test
win-test | SUCCESS => {
"changed": false
}
# ansible -i inventory -m test -a "state=changed" win-test
win-test | SUCCESS => {
"changed": true
}
# ansible -i inventory -m test -a "state=failed" win-test
win-test | FAILED! => {
"changed": false,
"failed": true,
"msg": "[Error] state is failed!!"
}
おわりに
この記事が初投稿です。
指摘・ツッコミお待ちしております。
初めて投稿する内容としてはニッチなところな気がしますが、これが誰かの役に立てれば幸いです。