(ここに書かれている内容は2015年2月13日時点のものです)
IDCFクラウドはCloudStackなので、EC2と同じくAPI経由で操作できます。
CloudStackのAPIはRESTっぽい感じなんですが、引数の形が手で書くのはつらいので、IDCFさんが提供しているcloudstack-apiというコマンドラインクライアントを使います。
CoreOSのcloud-config.ymlを指定してインスタンスの起動とかもできます。
IDCFクラウド公式ブログ記事の「3-2. CloudStackのUser Data機能を使ったcloud-init」というところに説明があります。
CloudStackのUser Dataについて、いくつか注意点があります。
- APIに引数として渡すデータはBase64エンコードし、改行を削除した文字列である必要がある
- cloudstack-apiコマンド等HTTP GETリクエストで送信できるUser DataはBase64エンコード後で2KBまで対応
- HTTP POSTリクエスト(User Data自体はPOSTのBody部分に記載)を使うと32KBまで対応
- Base64エンコード前のデータのバイト数が3の倍数ではない場合、正常に認識できない
最後の点があるため、上記の例では改行などを削除して合計546バイトにしています。
APIを実行する端末上で上記の内容のcloud-config.ymlを作成した後、Base64エンコードした文字列を取得します。
$ base64 cloud-config.yml | tr -d "\n" ;echo ""
I2Nsb3VkLWNvbmZpZwp1c2VyczoKICAtIG5hbWU6IGlkY2YKICAgIGdyb3VwczoKICAgICAgLSBzdWRvCiAgICBzc2gtYXV0aG9yaXplZC1rZXlzOgogICAgICAtIHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRREJYa1VheHdSWVBIamNjaUkwMHVPOEFCMXRnSUs3aDBLQVJZWTVKUzZKbGFIYUhSLzN5eDAySGJCdjVsRVBEc3o2eERWYjd2SE9USnBpTVhJVVV2SjRaNDgwQTZFRjB3SXdUQjB4VnZFbElSL0F6NnlzNEZrTzFBK2pvNnVkZXZvTG9iMVBPNFZ3d1pqcUZZK1lUTHRrR0JidHZycmJmUU5KVE1hZ1pUZjRaMk5ObVE0c0hJNmI0Z2U1d0UrQ0QrZkNFMXdTaDlJVStIaldwNndrS2FLUVhTZHZ6eEZGZjVsZjBOMFVpWkh6UnlFOTl2SzN0V3c5YStqeU5NWmIwNjdXWVBWL2FYR0IxRG9rbzN2OXgwemtsS0ZVeDRuSkczaUlRMDlmUUlYUVFVTU5WOGY1RnlwSnViell1K3V2eDgvelhRazk4Sng0dkk5alBWSlM2UzdkCmNvcmVvczoKICAgIHVuaXRzOgogICAgICAtIG5hbWU6IGRvY2tlci5zZXJ2aWNlCiAgICAgICAgY29tbWFuZDogc3RhcnQK
上記文字列を使って、先ほど作成した仮想マシンにUser Dataを設定します。
$ cloudstack-api listVirtualMachines -t id,name,group,state
+--------------------------------------+--------+-------+---------+
| id | name | group | state |
+--------------------------------------+--------+-------+---------+
| 3583dc29-5860-47aa-bc13-9fbb7ce50d46 | coreos | test | Running |
+--------------------------------------+--------+-------+---------+
$ cloudstack-api updateVirtualMachine --id 3583dc29-5860-47aa-bc13-9fbb7ce50d46 \
--userdata I2Nsb3VkLWNvbmZpZwp1c2VyczoKICAtIG5hbWU6IGlkY2YKICAgIGdyb3VwczoKICAgICAgLSBzdWRvCiAgICBzc2gtYXV0aG9yaXplZC1rZXlzOgogICAgICAtIHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRREJYa1VheHdSWVBIamNjaUkwMHVPOEFCMXRnSUs3aDBLQVJZWTVKUzZKbGFIYUhSLzN5eDAySGJCdjVsRVBEc3o2eERWYjd2SE9USnBpTVhJVVV2SjRaNDgwQTZFRjB3SXdUQjB4VnZFbElSL0F6NnlzNEZrTzFBK2pvNnVkZXZvTG9iMVBPNFZ3d1pqcUZZK1lUTHRrR0JidHZycmJmUU5KVE1hZ1pUZjRaMk5ObVE0c0hJNmI0Z2U1d0UrQ0QrZkNFMXdTaDlJVStIaldwNndrS2FLUVhTZHZ6eEZGZjVsZjBOMFVpWkh6UnlFOTl2SzN0V3c5YStqeU5NWmIwNjdXWVBWL2FYR0IxRG9rbzN2OXgwemtsS0ZVeDRuSkczaUlRMDlmUUlYUVFVTU5WOGY1RnlwSnViell1K3V2eDgvelhRazk4Sng0dkk5alBWSlM2UzdkCmNvcmVvczoKICAgIHVuaXRzOgogICAgICAtIG5hbWU6IGRvY2tlci5zZXJ2aWNlCiAgICAgICAgY29tbWFuZDogc3RhcnQK
↓この部分がよくわからないですね。
- cloudstack-apiコマンド等HTTP GETリクエストで送信できるUser DataはBase64エンコード後で2KBまで対応
- HTTP POSTリクエスト(User Data自体はPOSTのBody部分に記載)を使うと32KBまで対応
実際に試してみると、cloud-config.ymlが一定サイズを超えると、401というエラーコードの入ったJSONが返ってくるようになります。おそらく送信するデータが2KBを超えたタイミングでしょう。
IDCFクラウドの提供しているcloudstack-apiコマンドのコードを見ると、どうやらPOSTリクエストには対応していなさそう。
これを無理やりPOSTも遅れるように書き換えてみても、unable to verify user credentials and/or request signature
というエラーが返ってきました。
CloudStack自体のコードを読んでみると、この↓あたりからlogin
というAPIを先に叩いてJSESSIONIDというのをもらわなければPOSTリクエストを使うことはできないようでした。
https://github.com/apache/cloudstack/blob/master/server/src/com/cloud/api/ApiServlet.java#L277-L299
https://github.com/apache/cloudstack/blob/master/server/src/com/cloud/api/ApiServer.java#L785-L804
困りました。IDCFクラウドではCloudStackのlogin APIは提供されていません。
そんなわけで、現時点ではAPI経由で大きめのcloud-config.ymlを使う方法は無さそうです。