さくらのクラウド APIを使ってサーバを立ち上げてみよう
さくらのナレッジで記事を書くのにあたって、さくらのクラウドで頻繁にサーバを立ち上げたり、削除したりしています。さくらのクラウドではWebブラウザ向けに管理画面を提供していますので、そこでサーバを設定したり、ネットワークの変更ができるようになっています。
しかし何度も操作を繰り返したり、時にミスして立ち上げ直したりしていると面倒になってきています。そこでさくらのクラウドではAPIが公開されていますので、このAPIを使ってサーバを自動で立ち上げられるようにしてみました。
目次
さくらのクラウドでのサーバ立ち上げ手順
さくらのクラウドでサーバを立ち上げた経験がある方は分かると思いますが、サーバ立ち上げ中や設定中のステータス時にはGET/POST/PUT/DELETEなどのHTTPステータスやパラメータが表示されます。これは実際にAPIを叩いて実行されています。つまりこの手順と同じことをすればサーバが立ち上がる仕組みです。
一つのサーバを立ち上げる手順は以下のようになっています。
- サーバの作成
- ディスクの作成
- サーバとディスクの接続
- ディスクの修正
- 電源投入
このステップを踏んでいけばサーバが立ち上がります。
APIキーを取得する
さくらのクラウドをAPI操作するためには認証キーが必要です。設定画面のAPIキーメニューにて取得できます。
最初はキーがありませんので作成します。キーはアクセストークンとシークレットキーからなります。どちらも大事なので不用意に公開したりしないでください。間違って公開してしまった場合は削除して作り直すのが良いでしょう。
node用ライブラリを取得する
さくらのクラウドではnode用ライブラリを配布しています。GitHubのsakura-internet/node-sacloudリポジトリからダウンロード可能です。ライセンスはMIT Licenseとなっています。
$ npm install -g sacloud
でインストール可能です。インストールされるとsacloudというコマンドが使えるようになりますが、今回はライブラリを直接操作します。
設定ファイルを作成する
ホームディレクトリに .sacloud.json というファイルを用意します。内容は次のようになります。
{ "access_token": "APIのアクセストークン", "secret": "APIのシークレットトークン", "password": "サーバ接続用のパスワード", "public_key": ".ssh/id_rsa.pub" <- 公開鍵のパス }
実行してみる
今回作成したスクリプトはGistに公開しています。CoffeeScriptで作成しています。
実行は次のように行います(別途 npm install -g coffeescript が必要です)。
$ coffee new_server.coffee server1
server1 というのはサーバ名です。実行すると次のように標準出力が流れます。
$ coffee new_server.coffee server1 Instanse ready 0/20480 3520/20480 9792/20480 16256/20480 19456/20480 Disk ready Connected Configured Launched Got server info. Server launched. Let's command. :-) ssh core@133.242.17.208
これでCoreOSのサーバが一台立ち上がります。では順に説明します。
メイン処理
処理はとても簡単で、次のようになります。
sakura = new Sakura(JSON.parse(fs.readFileSync(file_path, 'utf-8'))) sakura.create_server(server_name).then (bol) -> console.log "Server launched." console.log "Let's command. :-) ", "ssh core@#{sakura.server.interfaces[0].ipAddress}"
設定ファイルを読み込んで、create_serverメソッドを実行しています。そうするとサーバ情報が返ってきますので、IPアドレスを表示しています。今回はあくまでも個人用としてCoreOS決め打ちになっていますので、サーバの接続もcore@にしています。
create_serverは次のようになっています。
create_server: (server_name) -> me = this me.server_name = server_name Promise.all([this.create_instance(server_name), this.create_disk()]) .then (results) -> me.server_id = results[0] me.disk_id = results[1] me.connect_server_disk() .then (bol) -> me.modify_disk() .then (bol) -> me.launch_server() .then (bol) -> me.get_server_info()
基本的にPromiseで順番に実行しているだけですが、最初のcreate_instance(サーバ作成)とcreate_disk(ディスク作成)は一緒に終わっている必要があるのでPromise.allを使っています。その後、connect_server_disk(サーバとディスクの接続)、modify_disk(ディスクの修正)、launch_server(電源投入)、get_server_info(サーバ情報取得)を順番に行っています。
サーバ作成処理
さくらのクラウドAPIは全体としてシンプルなので、殆どのメソッドが同じ形になっています。まずはサーバ作成処理です。
create_instance: (server_name) -> me = this return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'POST' path: 'server' body: Server: Zone : ID: 31001 # 石狩第1ゾーン ServerPlan: ID: 2001 # プラン/1Core-2GB Name: server_name Description: '' ConnectedSwitches: [ _operation: "internet", Scope: "shared" BandWidthMbps: 100 virtio: true ] Tags : [] ).send (err, result) -> console.log("Instanse ready") onFulfilled(result.response.server.id)
こちらもWeb APIを使った非同期処理になるのでPromiseで囲んでいます。後は /server へPOSTメソッドで情報を送信しているだけです。送っている情報としては、ゾーン(石狩第1または第2)、サーバのプラン、ネットワーク接続情報になります。
ディスク作成
次にディスクの作成です。
create_disk: -> me = this return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'POST' path: 'disk' body: Disk: Plan: ID: 4 Zone: ID: 31001 # 石狩第1ゾーン SourceArchive: ID: 112600559834 SizeMB: 20480 Connection: "virtio" Name: strftime("%Y/%m/%d %H:%M:%Sに新規作成されたサーバ") ).send (err, result) -> throw new Error(err) if err disk_id = result.response.disk.id id = setInterval( -> me.client.createRequest( method: 'GET' path: 'disk/' + disk_id ).send (err, result) -> if result.response.disk.migratedMB == result.response.disk.sizeMB console.log("Disk ready") clearInterval(id) onFulfilled(disk_id) else console.log("#{result.response.disk.migratedMB}/#{result.response.disk.sizeMB}") , 5000)
基本的にはサーバ作成と同じですが、注意点としてはアーカイブの選択があります。このIDはゾーンによって異なりますので注意してください。調べ方としてはWebのダッシュボードでアーカイブ選択に表示されている数字をメモする方法になります。
また、ディスクの作成が終わった後、データのコピー処理が行われるのでそのステータスを5秒おきにチェックしています。ディスクの作成が終わらないとサーバとディスクの接続ができませんのでご注意ください。
ディスクのコピーが終わったら同じくPromiseを終えています。
サーバとディスクの接続
サーバとディスクを接続するのはとても簡単です。
connect_server_disk: -> me = this return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'PUT' path: "disk/#{me.disk_id}/to/server/#{me.server_id}" ).send (err, result) -> console.log("Connected") onFulfilled(1)
出来上がったサーバとディスクのIDを使ってWeb APIを呼び出すだけで完了します。
ディスクの修正
ディスクの修正は設定ファイルで指定している公開鍵の取得とパスワードの設定を行っています。
modify_disk: -> me = this public_key = fs.readFileSync(process.env.HOME + "/" + me.config.public_key, 'utf-8') return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'PUT' path: "disk/#{me.disk_id}/config" body: Password: me.config.password SSHKey: PublicKey: public_key HostName: me.server_name ).send (err, result) -> console.log("Configured") onFulfilled(1)
こちらも分かりやすいかと思います。
サーバへの電源投入
いよいよ電源投入です。こちらはとてもシンプルです。
launch_server: -> me = this return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'PUT' path: "server/#{me.server_id}/power" ).send (err, result) -> console.log("Launched") onFulfilled(1)
サーバの情報取得
最後にサーバの情報を取得します。
get_server_info: -> me = this return new Promise (onFulfilled, onRejected) -> me.client.createRequest( method: 'GET' path: "server/#{me.server_id}" ).send (err, result) -> me.server = result.response.server console.log("Got server info.") onFulfilled(1)
これで指定したサーバだけの情報が得られます。
まとめ
いかがでしょうか。さくらのクラウドAPIを使うと、クラウドにサーバを立てるという一連の作業がステップバイステップで見られて面白いですよね。今回は石狩第1、かつCoreOSでといったかなり決めうちの立ち上げになっています。パラメータを修正すれば、自分好みの設定を作成するのも難しくはないと思います。
企業などでクラウドを立ち上げる場合、用途に合わせてパラメータはだいたい固定値で設定されると思いますので、予めこうやって準備しておけば後はコマンド一つでサーバ立ち上げができるようになるでしょう。ぜひご活用ください!