ちゃんるいすのブログ

オタクエンジニアの雑記

Go で作る Ansible モジュール


Ansible Advent Calendar 2019 2日目ーーー
qiita.com

1日目は sky_jokerxx さんのこちらの記事でした。
sky-joker.tech

2018 の Ansible Advent Calendar ではこんな記事を書いていた。
blog.luispc.com

モジュールを作った経緯

社内で使っているコンポーネントの管理を IaC にしたかった。
コンポーネントを作った人は Terraform のモジュールを提供されたけど、Ansible のモジュールを作って運用したかった。

Go で Ansible モジュール作るのは簡単

type Response struct {
	Msg     string `json:"msg"`
	Changed bool   `json:"changed"`
	Failed  bool   `json:"failed"`
}

これを、json で標準出力に返せばいいだけ。
Failed じゃないなら os.Exit(0) で返せばいいし、Failed なら os.Exit(1) で返す。

バイナリを作る

僕は会社では Mac、家では Linux なのでバイナリは LinuxDarwin 向けに作る。
こんな感じの Makefile を用意しておく。

build-darwin:
	@GOOS=darwin go build -o ../library/hoge_node_darwin cmd/hoge/node/main.go
	@GOOS=darwin go build -o ../library/hoge_pool_darwin cmd/hoge/pool/main.go
	@GOOS=darwin go build -o ../library/hoge_monitor_darwin cmd/hoge/monitor/main.go
	@GOOS=darwin go build -o ../library/hoge_pool_member_darwin cmd/hoge/pool_member/main.go
	@GOOS=darwin go build -o ../library/hoge_vip_darwin cmd/hoge/vip/main.go
	@GOOS=darwin go build -o ../library/hoge_address_darwin cmd/hoge/address/main.go
	@GOOS=darwin go build -o ../library/hoge_address_set_darwin cmd/hoge/address_set/main.go
	@GOOS=darwin go build -o ../library/hoge_policy_darwin cmd/hoge/policy/main.go
build-linux:
	@GOOS=linux go build -o ../library/hoge_node_linux cmd/hoge/node/main.go
	@GOOS=linux go build -o ../library/hoge_pool_linux cmd/hoge/pool/main.go
	@GOOS=linux go build -o ../library/hoge_monitor_linux cmd/hoge/monitor/main.go
	@GOOS=linux go build -o ../library/hoge_pool_member_linux cmd/hoge/pool_member/main.go
	@GOOS=linux go build -o ../library/hoge_vip_linux cmd/hoge/vip/main.go
	@GOOS=linux go build -o ../library/hoge_address_linux cmd/hoge/address/main.go
	@GOOS=linux go build -o ../library/hoge_address_set_linux cmd/hoge/address_set/main.go
	@GOOS=linux go build -o ../library/hoge_policy_linux cmd/hoge/policy/main.go
build:
	$(MAKE) build-darwin
	$(MAKE) build-linux
test-darwin:
	$(MAKE) build-darwin
	@cd .. && ansible-playbook -i inventory hoge_darwin.yml -vv
test-linux:
	$(MAKE) build-linux
	@cd .. && ansible-playbook -i inventory hoge_linux.yml -vv

使う

---
tasks:
  - name: create node
    hoge_node_linux:
      name: unchi
      address: 10.194.4.32
      port: 80
      state: present

上記のタスクを用意したとき hoge_node_linux というファイル名のバイナリが ./library というディレクトリにあれば使える。
ただこれだと、Darwin でこのタスクは実行できないので、main.yml で分岐させる。

---
- name: get os
  command: uname
  delegate_to: 127.0.0.1
  become: no
  register: executed_os

- import_tasks: linux.yml
  when: executed_os.stdout == "Linux"

- import_tasks: darwin.yml
  when: executed_os.stdout == "Darwin"

これは Go で作る上でしょうがないけど、まあ仕方ない。

最後に

少しでも Go が書けるなら Ansible モジュールも簡単に作れる。

あと、この記事の趣旨とは違うけど Ansible はよく ”VM にパッケージ入れたり設定するツール” という思い込んでる人がいるかもしれませんが
AWS を始めとした GCP や Azure などのパブリッククラウド、OpenStack や Proxmox のリソース自体も弄れることを知って欲しいです。
なんだったら、Alibaba にも対応してます。

パブリッククラウドは頻繁に新しいサービスがローンチされますが、Ansible は結構早めにそれに追従してくれてます(モジュールを作って PR 出せば良いだけ)。
リソース管理を Terraform じゃなくて、Ansible という手もアリだと思ってます。

クラウド系のモジュール

docs.ansible.com

ということで2日目はこれで終わります。
3日目は comefigo さんです👳