Elaboration in, Garbage out

Twitt*r ではメモできない何かそれ的なモノ・コトを

AWS Cloud9 を触ってみる。

まえがき

そういえば転職してからブログ書く習慣が完全に途絶えてしまいました。。 前職は仕事が面白くない余裕があったのでブログをガンガン書こうと思ってましたが、 今は新しい仕事に興味が湧いていてこっちが疎かになってしまって。

でもこのままではまずい!ということで、手始めに前から構想していた

  • タブレットを持ち歩いて
  • ブラウザで自分の VM 上にある Web IDE を立ち上げ開発する

という環境整備から初めます。業務用 PC とは別に MacBook Air を持ち歩くのは思いし嫌だ!というのが理由であり、業務用 PC でこっそり開発するのが目的ではありませんよ。

SaaS もあるやん

paiza.hatenablog.com

SaaS の Web IDE は便利そうですが、触ってみるとやっぱり片手落ち感があります。 私の場合は結局色々 Bash でコマンドを叩く必要があるからですね。

だから、自前 VM 上 Web IDE を準備してしまえ、っていう着想で色々調べてました。が、つい 2017/12 頭に AWS からめちゃくちゃ便利な物が出ました。

aws.amazon.com

自前 Web IDE 構想を考えると認証どうすんだっけ・・・と気になりますが(私だけ?)、AWS なら IAM でユーザ管理できる*1し二要素認証もバッチリです。

Cloud9とは

ブラウザ内で動く統合開発環境です。SaaS 版も前からあったらしいのですが、AWS に移行したことで色々紛糾しているよう:AWS Cloud9 has launched! - Cloud9 Support - Cloud9 Community

Prerequisite

公式には多分 Amazon Linux なのですが、私はいつの間にか CentOS 派になってしまったので CentOS で頑張ります。

  • CentOS 7
  • Node(どうやら 0.6.16 以上が必要なので epel で入れるのは微妙そう。)
  • Cloud9 用ユーザ(セキュリティのことを考えると特権ユーザを渡したくないですよね・・・!)

Amazon Linux でもいいんですけどね。ええ。

dev.classmethod.jp

ただ、何が動いているかいちいち全て調べないといけないのはなぁ・・・という凝り性なので。。

Setting Up

専用 EC2 インスタンスを立ち上げるのが一番ラクで、3 分もしないうちに使えるようになりますし、最近追加されたハイバネート機能もあり安価でかつ高性能開発環境を作ることができます。CentOS でもハイバネート機能使えるようにできないかな。。

Warning

現状 c9.ide.lambda.docker が CentOS だとうまく入れられないようです *2https://forums.aws.amazon.com/thread.jspa?messageID=816676&tstart=0 とりあえず最初だけ sudo をパスワード無しで実行出来るようにしておくと、 勝手に Docker をインストール Docker 上で lambda 用コンテナを動かすための環境セットアップを裏で実行されます。これは流石に通知無しでやられるのはつらい。

今後

本番はこれからです。

余談

cloud9 でも出来ますが、コードの共同編集って今後どんどん広がるんでしょうね。 Office 365 でも、Google Doc 系でもすでに広まってますが、コード界隈だと atom や VIsual Code も対応し始めたりし。面白そうな世界です。

*1:ただし IAM 上でユーザ管理をしない運用だとつらそう。

*2: Forum 見ると多分 Ubuntu

JupyterHub/Swarm Mode で苦戦中

JupyterHub を Swarm Mode で動かしたいんだけれども、どうやら Swarm Mode は 1.12 以前の Swarm とは違い、外部からのコンテナ操作ができないみたいです。

forums.docker.com

1.12 以前の Swarm であれば、

$ docker run -d -p 4000:4000 swarm manage \
-H :4000 --replication \
--advertise 172.30.0.161:4000 \
consul://172.30.0.165:8500

みたいなコマンドで 4000 で Docker 操作をできるようにし、 JupyterHub がその 4000 番経由でコンテナを立ち上げる、といったことが可能でした。 ただ、これをセキュアにするためにはサーバ証明書だけではなくクライアント証明書も作成しないといけないのですごく大変 *1

証明書周りがラクな Swarm Mode でなんとかならないかと思っていたら、次の issue を発見。

github.com

  • dockerspawner/JupyterHub は Docker 1.12 以前の Docker Swarm で動作を想定。
  • 上述の issue にある jupyterhub_config.py には 1.12 以前の Docker Swarm で動作させる config を作成。

ただ、このコメント「SwarmSpawner」をもっと速く知ってればよかった!とあり、おっ、と思い調べたらどうやら次のレポジトリがそれのようです。

github.com

とりあえず動かしてみたけど、ThreadPool まわりでエラーが出たので、とりあえずやっつけ修正でプルリクを送送付。

Swarm Mode で Service を開始させるまでには至ったけど、次のエラーがでました。

  • エラー
[W 2017-02-25 09:58:08.099 JupyterHub utils:88] Failed to connect to http://jupyterhub-cdc872db616ac66adb3166c75e9ad183-1:8888/user/centos ([Errno -2] Name or service not known)
  • 生存確認
$ docker service ls
ID            NAME                                           MODE        REPLICAS  IMAGE
ivcdyicugvjg  jupyterhub-cdc872db616ac66adb3166c75e9ad183-1  replicated  0/1       jupyterhub/singleuser:latest

Swarm Mode 上での Service Discovery も準備する必要があるようですが、いったんここで力尽きました。。

forums.docker.com

にあるように、Swarm Mode では Service Discovery 用のツールはいらなくなったけど、あると便利ですね。

*1:Swarm Mode が出てきた経緯でもある

Docker 1.12/1.13 でクラスタ機能が付いたらしい。

はじめに

以前 JupyterHub を Swarm/Docker 上にデプロイしようとするために、 証明書周りをがっつりこねこねする Ansible を書いていており、リファクタしないとなと思いはや一年。。 忙しさにかまけると何もできないですね。。 で、久々に手を入れようと思ったのですが、 次の2つをしってびっくり。

  1. RHEL, CentOS7 系は Linux Kernel 3.12 未満であるのみ関わらず VXLAN を利用可能
  2. Docker 3.12 からオーケストレーション機能が標準で入る。

一つ目は、調べたらふつーに出てきましたね。。はい。 二つ目は、証明書周りがかなり楽になっていて、証明書周りを Ansible で触らなくてすみそうです。 しかも consul や etcd も不要になったとのことなので、余計な管理もしなくて済みそうです。

https://pocketstudio.net/2016/06/21/docker-1-12-build-in-orchestration-translate/

で、実際に触ってみましょう。

参考

https://docs.docker.com/engine/swarm/swarm-tutorial/

やはり公式ドキュメントが一番です。

Vagrant/Ansible の準備

大したモノじゃないけど、あると色々便利な vagrant/ansible のスクリプトをベースに、vagrant up で初期設定ながします。

  • Docker の repository file を /etc/yum.repos.d/docker.repo に格納して
  • Docker のインストール・vagrant で実行可能にしておく程度です。

github.com

Docker Swarm の構築

まずは Docker Swarm の構築 *1

[vagrant@mgmt ~]$ docker -v
Docker version 1.13.0, build 49bf474
[vagrant@mgmt ~]$ docker swarm init  --advertise-addr  192.168.33.41:2377
Swarm initialized: current node (t98hh0yrs83yny7n2gkuphwrn) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-1obl48uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-2yyyyyyyyyyyyyyyyyyyyyyyy \
    192.168.33.41:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

続いて、Docker ワーカー用の VM に上述のコマンドを実行してあげます。

[vagrant@dc01 ~]$  docker swarm join \
    --token SWMTKN-1-1obl48uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-2yyyyyyyyyyyyyyyyyyyyyyyy \
    192.168.33.41:2377
[vagrant@dc02 ~]$  docker swarm join \
    --token SWMTKN-1-1obl48uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-2yyyyyyyyyyyyyyyyyyyyyyyy \
    192.168.33.41:2377

ノードが追加されているか確認しましょう。

[vagrant@mgmt ~]$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
f76rx5jootznd1w8kjhj9palz *  mgmt      Ready   Active        Leader
i9be3upvx5x76l7a7yajko619    dc01      Ready   Active
kkt3lk0bf37cqr5snz7jnni6f    dc02      Ready   Active

次に、公式ドキュメントでは docker.com に ping を打つだけのコンテナを動かしてます。 ping of death 対策してるのかな。。と思い、ここでは割愛。 とりあえず nginx を一つのコンテナで動かしてみましょう。

[vagrant@mgmt ~]$ docker service create \
  --name my-web \
  --publish 8080:80 \
  --replicas 1 \
  nginx

https://docs.docker.com/engine/swarm/ingress/ にある通り、manger, worker ノードすべて 8080 番をリッスンします。 ちなみに、ローカル環境では全ての VM が 8080 を Listen するまでに 3 分ぐらいかかりました。

[vagrant@mgmt ~]$ curl -I 192.168.33.41:8080
HTTP/1.1 200 OK
Server: nginx/1.11.9
(略)

[vagrant@mgmt ~]$ curl -I 192.168.33.42:8080
HTTP/1.1 200 OK
Server: nginx/1.11.9
(略)

[vagrant@mgmt ~]$ curl -I 192.168.33.43:8080
HTTP/1.1 200 OK
Server: nginx/1.11.9
(略)

ほんとに全台 Listen し始めてる。あとはコンテナ数を増やしたり、HAProxy で設定すれば手軽にかんたん冗長構成ですね。

*1:どうやら swarm init のオプションが 1.12 と 1.13 で違うようです。

ASUS ZenPad S3 8 (Z581KL) 買ったという話

だって、iPad 高いんだもの。

Motivation

自宅 PC、ノート PC、スマホタブレットタブレットすべて Apple 製品、会社で使用する PC も Apple 製品にする、という信者っぷり。 ただ、タブレットiPad 3rd で古くて、自炊 pdf を読むともっさりするので、新しいのがタブレットがほしいなーと思っていた。あと、Wi-Fi ルータで UQ Mobile を使っていいるので、せっかくなら WiMAX 2+ の周波数帯域 *1 を使えるタブレットにしたい。

Comparison

  • iPad Pro 9.7inch: 82,944 円
  • iPad mini 4: 61,344 円
  • ZenPad S3 8: 39,000〜40,000 円
  • MediaPad T2 Pro: 23,000〜24,000 円

*2

前々から気になっていた iPad Pro 9.7inch を買おうと思っていた。 ただ、iPad については、来年モデルが刷新されるなどの色々噂があって、なら来年でいいかーと毎年後回しにしていた。今年も、結局噂に惑わされ、やすいのでいっかーとなった。

安くてそれなりのものがいいなーと思って Nexus 7 も良いかなと思っていたんだけれども、WiMAX 2+ の周波数帯域に対応してないので断念。新しいモデルがあると思っていたのだけれども、2013 年以降出てない&今年も何かお流れな雰囲気なのね。

で、Huawei の MediaPad か ASUS の ZenPad かの二択になったのですが、自炊電子書籍レンダリング能力が大事。というわけで、CPU/GPU 性能が(も)良い ZenPad *3の方を購入。

Impression

  • 充電する際の USB の規格は Type-C。
  • 自炊した pdf をストレスなく読めるので良い(レンダリング終わるまで 1 秒掛からない程度*4)。
  • 文字がちょっと小さくても大丈夫であれば、見開き表示もいける。
  • UQ Mobile の WiMAX 2+ の回線使えれば速い。

平日・夜間は困らない程度で、爆速のときもあってわりと快適*5f:id:huacha:20161022122009j:plain

Limitation

  • 端末自体は通話ができると歌ってるけど、au 系の SIM では通話・SMS が使えない。 *6 まあ、タブレットで通話しようとは思わないかな。スマホあるので SMS は使わないし。
  • 通話・SMS ができないのと同じ理由で、LTE (4G) のみの設定が必要。LTE が入る地域であればまあ問題ない。*7

Epilogue

ZenPad Sの USB の規格が Type-C なので MacBook がほしくなった。

*1:TDD-LTE Band 41: 2.5GHz

*2:執筆当時の新品のおおよその価格(税込み)です

*3:MediaPad T2 Pro は CPU 1.5GHz x 4 + 1.2GHz x 4 (Snapdragon 615), GPU Adreno 405。それに対し、ZenPad 3S 8 は CPU 1.8GHz x 2 + 1.2GHz x 4 (Snapdragon 650), GPU Adreno 510

*4:電子書籍リーダとして SideBooks を使用

*5:UQ Mobile の宣伝みたいだけど気にしない

*6:SIMフリー端末で使うau回線 ~LTE onlyで乗る通信快速~ | Gadget and Radio が一番わかり易い。Android のダイヤルで「*#*#4636#*#*」を押して「IMS登録をON」「IMSでのSMS機能をON」にしても、機能しない(機能しないことが普通らしい)

*7:通話・SMSを使いたい、3G 回線しか拾えない地域で使いたい、という用途の場合、au 系の MVNO はしばらく様子見をした方がいいですね。

chat の open source をもう一度調べてみた

まえがき

久々の投稿です。3月末までドタバタ+4〜5月の旅行熱のほとぼりがさめた頃、ブログの存在を思い出しました笑 最近 Being Geek という本を読んでいるのですが、メールの返信でもブログの更新でも、遅れた場合には何かと言い訳をしたくなるということを実感しております。 www.oreilly.co.jp

で、本題です。技術の進展ではないのですが、open source でも色々世の中の動きは変わるのですね。 ちなみに本記事の参考は次の URL です。

簡単な調査

日本人大好き比較表です(2016/05/22 時点でのスター)

name スター fork
let's chat 7990 1144
Rocket.Chat 7212 1470
zulip 3859 549
mattermost 7972 869

f:id:huacha:20160522123645p:plain

  • Google Trend には書いておりませんが、slack がもちろんダントツです。slack 入れるとムスカ様になります。
  • Zulip が一時期大流行したっぽいですが、なんかはやってないみたいですね。なんか使いにくいんですかね。
  • いきなり mattermost がアツくなってますね。Google Trend 上では Hip Chat と同じぐらいになってます。

今から chat ツールを入れるなら MatterMost 一択ですかね。Gitlab を Omnibus Installer で使っている人は準備しやすいのでは(特に私)。 WebHook も用意されているので、Hubot との連携も簡単そうです。

qiita.com qiita.com

ただ、gitlab との結合度も気になるので、その辺びみょ〜〜な感じな人は Rocket.Chat が良いのかな。このご時世、いかに簡単にデプロイさせるかが大事なようで、Rocket.chat はドキュメンテーションにすっげー力いれてます。例えば、このドキュメントには ansible(ほか、Docker, vagrant、他 PaaS 15 種類!)でデプロイする方法を載せています。この辺り、zulip との差なんだろうなー。

とりあえず、Mattermost をデプロイしてみます。

iscsi 喋られるようになりたい(on CentOS7)

はじめに

機械語は流石にアレですが、iSCSI をバックエンドで雑に作る必要があるので色々調査。

知り合いにどやされて ZFS を使おうとしてみました。

メモリ(L1ARC)や SSD(L2ARC, ZIL)でフル SSD でなくても、ストレージの IO をよさ気にキャッシュしてくれる機能、あれめっちゃよさ気やんー!って気に入ったら Oracle のお蔵入りになってたんですね。ふぁーい。

もちろん、ZFS on Linux で頑張っている人たちはいて、NFS とかは動く?動かない?かよくわからないらしいし、iSCSI をしゃべる機能が入ってない *1

それで色々ググっていたら、 targetci やら netbsd から移植された netbsd-iscsi が使えるらしいとのこと。なんか後者のほうが楽そうだから、netbsd-iscsi を使ってみた。

コマンド

参考

ここ(ftp://ftp.netbsd.org/pub/NetBSD/misc/agc/HOWTO-iSCSI-target.txt)がすべてなんですけどね。

vagrant

vagrant で virtuabox の disk を追加できることに最近気づきました。いい時代(?)ですね。

# -*- mode: ruby -*-
# vi: set ft=ruby :
ENV['VAGRANT_DEFAULT_PROVIDER'] = "virtualbox"
Vagrant.configure(2) do |config|
  config.vm.box = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.1_chef-provisionerless.box"
  config.vm.network "private_network", ip: "192.168.33.151"

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "4096"

    # You can add a disk with below scripts

    file_to_disk = "/path/2/your/location.vdi"
    if not File.exist?(file_to_disk) then
      vb.customize ["createhd",
                    "--format", "VDI",
                    "--filename", file_to_disk,
                    "--size", 100 * 1024]
    end
    vb.customize ['storageattach', :id,
                  '--storagectl', 'SATA Controller',
                  '--port', 1,
                  '--device', 0,
                  '--type', 'hdd',
                  '--medium', file_to_disk]
  end
end

iSCSI-Target をインストール

EPEL パッケージを入れれば一発です。

# yum install epel-release
# yum install netbsd-iscsi

設定

とにかく喋ればおっけーなので、/etc/iscsi/targets にデバイスファイルをダイレクトに使用します。 心配な人は mdadmRAID 組むとか、RAID で組んだファイルシステム上のファイルを指定すれば *2 オッケーですね。

  • /etc/iscsi/targets の中身
# extents       file            start   length
extent0         /dev/sdb        0       50GB
extent1         /dev/sdb        53687091201     49GB

# target        flags   storage         netmask
target0         rw      extent0         0.0.0.0/0
target1         rw      extent1         0.0.0.0/0
  • 設定の反映
# iscsi-target restart
Reading configuration from `/etc/iscsi/targets'
target0:rw:0.0.0.0/0
  extent0:/dev/sdb:0:53687091200
target1:rw:0.0.0.0/0
  extent1:/dev/sdb:53687091201:52613349376
DISK: 1 logical unit (104857600 blocks, 512 bytes/block), type iscsi fs
DISK: LUN 0: 51200 MB disk storage for "target0"
DISK: 1 logical unit (102760448 blocks, 512 bytes/block), type iscsi fs
DISK: LUN 0: 50176 MB disk storage for "target1"
TARGET: TargetName is iqn.1994-04.org.netbsd.iscsi-target

IQN iqn.1994-04.org.netbsd.iscsi-target 上で いわゆる LUN target0target1 が作成された、ということですね。

iSCSI のクライアント側の設定

イニシエータ (Initiator)と呼ぶらしいですね。参考はこちら。

www.server-world.info

  • イニシエータのインストール
# yum -y install iscsi-initiator-utils
  • IQN の設定
# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1994-04.org.netbsd.iscsi-target

これで、接続してみます。

# iscsiadm -m node --login 
Logging in to [iface: default, target: iqn.1994-04.org.netbsd.iscsi-target:target0, portal: 192.168.11.49,3260] (multiple)
Logging in to [iface: default, target: iqn.1994-04.org.netbsd.iscsi-target:target1, portal: 192.168.11.49,3260] (multiple)
Login to [iface: default, target: iqn.1994-04.org.netbsd.iscsi-target:target0, portal: 192.168.11.49,3260] successful.
Login to [iface: default, target: iqn.1994-04.org.netbsd.iscsi-target:target1, portal: 192.168.11.49,3260] successful.

接続?でログイン?何が変わった?と、気になりますが、実はディスクドライブが増えています。

# cat /proc/partitions 
major minor  #blocks  name

   8        0   62522712 sda
   8        1     512000 sda1
   8        2   57815040 sda2
   8        3    4194304 sda3
   8       32   52428800 sdc
   8       16   51380224 sdb
[root@localhost vagrant]# 

おおー!となったので、今度は切断(ログアウト)してみます。

# iscsiadm -m node --logout;echo; cat /proc/partitions 
Logging out of session [sid: 3, target: iqn.1994-04.org.netbsd.iscsi-target:target0, portal: 192.168.11.49,3260]
Logging out of session [sid: 4, target: iqn.1994-04.org.netbsd.iscsi-target:target1, portal: 192.168.11.49,3260]
Logout of [sid: 3, target: iqn.1994-04.org.netbsd.iscsi-target:target0, portal: 192.168.11.49,3260] successful.
Logout of [sid: 4, target: iqn.1994-04.org.netbsd.iscsi-target:target1, portal: 192.168.11.49,3260] successful.

major minor  #blocks  name

   8        0   62522712 sda
   8        1     512000 sda1
   8        2   57815040 sda2
   8        3    4194304 sda3

なるほどこれは便利そう!

おわりに

  • Listen を 0.0.0.0/0 にしている点、認証が全くないので、本番では使わないよう。
  • というか、遅すぎて本番環境では使い物にならないはず。
  • 書いている途中で気付きましたが、CentOS 7.2 がやっと出たんですね。

*1: PR はだいぶ昔に通ってるみたいだが、いつの間にかなくなっている?

*2:http://tech-tw.blogspot.jp/2009/05/netbsdiscsi-target1-target.html

ansible の libvirt モジュールがあったので使おうとしてみた。

動機

Production 環境でもダイジョーブな、 Linux での仮想環境をさくっと作りたい、でもなんちゃら Stack を入れるのはちょっと重すぎ!ていうわけで、手軽に KVM で動かせればなーという動機です。探したら別の手段ありそうですが。そこ Docker でいいじゃんとは言わない。

で、色々調べていた所、ansible のモジュール virt を発見:virt - Manages virtual machines supported by libvirt — Ansible Documentation

怪しい匂いがする、というところで、KVM を勉強するついでに触ろうとしました。

動作環境

DigitalOcean は日本に進出しないみたいですかねー。DigitalOcean は vagrant 用のプラグインを公開しているので、それを使うと楽です。

KVM の操作

必要なものの準備

最低限のパッケージと OS イメージは準備しておく。

- name: Ensure kvm packages are installed
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - libvirt
    - qemu-kvm
    - bridge-utils
    - libvirt-python
- name: Ensure Centos 7 ISO file is downloaded
  get_url:
    url: http://ftp.jaist.ac.jp/pub/Linux/CentOS/7/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso
    dest: /download/path/to/CentOS-7-x86_64-Minimal-1511.iso
    sha256sum: f90e4d28fa377669b2db16cbcb451fcb9a89d2460e3645993e30e137ac37d284

get_url で何回もダウンロードさせないよう、dest はファイル名まで指定するという基本テク?ですね。

virt モジュールを使う

libvirt でいうところの define コマンドを使う

では virt モジュールで指定しましょう。

stackoverflow.com

にあるように、XML は実は文字列を指定するものです。ファイル名であれば {{lookup('template', 'your_define.xml.j2')}} のようにしようね、とのことです。ちなみに lookup('template', path) も、roles/some_role/template ではなくroles/some_role/file を探しに行くようです。こんなエラーがでました。

fatal: [machine1] => Failed to template {{ lookup('template', 'centos7_def.j2') }}: unable to read /path/to/roles/some_role/files/centos7_def.j2

壮大なるフェイントじゃないか。だからといって、template ファイルを flle ディレクトリに置くのは気持ち悪い。というわけでこんな感じ

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"

なんだかなー感あるのは気にしない。これを実行すると、

[vagrant@digital_ocean_host ~]$ sudo virsh list --all
 Id    名前                         状態
----------------------------------------------------
 -     centos7_temp                   シャットオフ

とでます。ちなみに、XMLname を指定しないと怒られます。

<domain type='kvm'>
  <name>centos7_temp</name>
  (後略:最後に貼り付け)

と指定してます。VM の定義はできましたが、なんかやな予感……

define した VM を走らせる。

さて、定義した VM を走らせてみましょう。タスクは次のようにします

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"

- name: Ensure VM is started
  virt:
    name: centos_via_ansible
    state: running
    uri: qemu:///system

実行結果

TASK: [some_role | Define VM using the XML file] ********************************* 
failed: [digital_ocean_host] => {"failed": true}
msg: operation failed: domain 'centos7_temp' already exists with uuid 6106bbb7-a310-43e8-b94e-576d00e98b3e

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/Users/******/site.retry

digital_ocean_host          : ok=1    changed=0    unreachable=0    failed=1   

冪等性がないようです。ちなみに、公式 virt モジュールのドキュメントにも

in addition to state management, various non-idempotent commands are available. See examples

と、冪等性なんてないよ!といってます。

では Ensure VM s Started だけで実行してみます。

TASK: [some_role | Ensure VM is started] ***************************************** 
failed: [digital_ocean_host] => {"failed": true}
msg: virtual machine centos_via_ansible not found

FATAL: all hosts have already failed -- aborting

やな予感的中。ちなみに、先ほど2つのタスクを同時に実行しても同じ結果です。そのため結局 XML の方に合わせました。

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"
- name: Ensure VM is started
  virt:
    name: centos_temp
    state: running
    uri: qemu:///system

この後しばらく libviet の VM 定義ファイル(XML)と格闘する

結局格闘し続けてます。

おわりに

virt-install というツールが優秀すぎて、ansible の virt モジュールを使う気がなくなりました。まずは KVM をがっつり勉強しなさいっていうことですね、はい。

そのため、libvirt での VM 定義ファイルをふつーに勉強すれば、おそらく virt-install ではなく ansible の virt モジュールと template エンジンでうまいこと様々なことが出来そうですね。

また、virt-install でも virt モジュールでも、どちらでも KickStart が必要ですね。kickstart と、ansible または virt-install のどちらか一つを組み合わせると無人で VM デプロイが可能ですね。この辺が見えてきてよかったかなーと。もうちょっと virt モジュールは頑張っても良かったのでは