月別アーカイブ: 2014年9月

AWS 環境の自動停止スクリプト

AWS を必要な時だけ立ち上げておきたいんだけど、人が操作するとどうしてもうっかり落とし忘れてしまう。
そこで、SDK を使うことである時間が来た際に自動で落とすような状態にしておきたい。

立ち上げるのは、必要に応じて自分で手動で行えばいいので、あくまで落とすことを優先させる。

AWS の SDK はいろいろな言語で出ているが、今回は Ruby を使ってみることにした。
あまりこれまで触れたことのない言語だったので。
理由はそれだけ。面白そうだったからに近い。

EC2 を落とすことは比較的簡単にできる。

予め、定義を作っておいて

[aws-config.yml]
access_key_id: <ACCESS_KEY_ID>
secret_access_key: <SECRET_ACCESS_KEY>
ec2_endpoint: ec2.ap-northeast-1.amazonaws.com

 

止めるための文を書く

[stopall-ec2.rb]
require 'aws-sdk'

AWS.config(YAML.load(File.read("./aws-config.yml")))

ec2 = AWS::EC2.new

ec2.instances.each do |ins|
  ins.stop if ins.status == :running
end

 

EC2 は比較的すんなりと行ったんだけど、RDS はよくわかっていない。

RDS の場合、そもそも停止という機能が存在していないため、本来の停止手順としては

  1.  一世代前の Snapshot の削除
  2. Snapshot の作成
  3. Instance の Delete

で、起動時には

  1. Snapshot からの RDS 作成
  2. セキュリティグループやパラメータグループ付け替え
  3. RDS インスタンスの再起動

という感じになると思う。
Snapshotをいつ削除するのかは好みなのかもしれないが、作成直前まで保持しておけば
バックアップとしても使えるし、もう少し手を加えて世代管理をしてもいいと思う。

EC2 と異なり、RDS は Snapshot からの起動となるので、手操作による名前付けミスは避けたい。
そういう意味では、起動まで自動化したくなるところではあるかな。

ただ、そもそも RDS の一覧が取れないように感じる。

[stopall-rds.rb]
require "aws-sdk"
rds = AWS::RDS.new(
  :access_key_id => <ACCESS_KEY_ID>,
  :secret_access_key => <SECRET_ACCESS_KEY>,
  :rds_endpoint => <RDS_ENDPOINT_URL>
)

rds.db_instances.each {|instance|
  p instance.endpoint_address
}

 

試しに Github 上で見かけたコードを元にこんなのを書いてみたけど、接続の時点で

C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `initialize': execution expired (Net::OpenTimeout)
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `open'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `block in connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:877:in `connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:857:in `start'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/connection_pool.rb:321:in `start_s
ession'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/connection_pool.rb:125:in `session
_for'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/net_http_handler.rb:55:in `handle'

from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:253:in `block in make_sync_re
quest'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:289:in `retry_server_errors'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:249:in `make_sync_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:511:in `block (2 levels) in c
lient_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:391:in `log_client_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:477:in `block in client_reque
st'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:373:in `return_or_raise'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:476:in `client_request'
from (eval):3:in `describe_db_instances'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/rds/db_instance_collection.rb:56:in `_each_i
tem'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection/with_limit_and_next_token.rb
:54:in `_each_batch'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection.rb:80:in `each_batch'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection.rb:47:in `each'
from stop-rds.rb:11:in `<main>'

のようにタイムアウトしてしまう。

と、ここで RDS 側の Firewall 関連の設定じゃないかと気づく。
RDS の構築を自分で行った環境ではなかったので気づくのが遅れた。

RDS を構築する際、 “Enable Public Access” って項目があって、通常は同じ VPC 内からのアクセスのみ許すようになっていた。
一時的にこれを変更して試してみたら、エラー内容が変化した

C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:918:in `connect': SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (OpenSSL::SSL::SSLError)
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:918:in `block in connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/timeout.rb:66:in `timeout'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:918:in `connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:857:in `start'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/connection_pool.rb:321:in `start_session'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/connection_pool.rb:125:in `session_for'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/http/net_http_handler.rb:55:in `handle'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:253:in `block in make_sync_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:289:in `retry_server_errors'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:249:in `make_sync_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:511:in `block (2 levels) in client_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:391:in `log_client_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:477:in `block in client_request'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:373:in `return_or_raise'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/client.rb:476:in `client_request'
from (eval):3:in `describe_db_instances'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/rds/db_instance_collection.rb:56:in `_each_item'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection/with_limit_and_next_token.rb:54:in `_each_batch'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection.rb:80:in `each_batch'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/aws-sdk-v1-1.52.0/lib/aws/core/collection.rb:47:in `each'
from stop-rds.rb:17:in `<main>'

 

はて・・・。困ったな。

ちなみに、

rds.db_instances["<INSTANCE_ID>"]

という形では AWS:RDS:DBInstance オブジェクトへアクセスできる。ここから delete を呼び出すことは出来そうなので、ID を指定すればできそうだ。

逆に、 EC2 のように each で無条件にインスタンスを落とすことは出来ないのかもしれない。

AWS:RDS 以外に AWS:RDS:Client も RDS の操作する手段としてはあるので、こちらを使えばもしかしたらいけるのかな?
エラーとなっている、 db_instance_collection の each_item 実装を見てみると client.describe_db_instances を呼び出しているみたいなので、
AWS:RDS:Client の使い方を習熟することがエラー解決への近道なのかもしれない。

まぁ、実際の問題としては RDS がそんなに増えることはないだろうから、とりあえずこれでやってみようかな・・・。

なんか、もうちょっとうまいこと行くとうれしいんだが。。。

エクセルのファイルサイズがやけに大きかったお話

少しエクセルで資料を作っていたら、1シートで20行未満、20列未満という程度の情報量に対してファイルサイズが 5M を超えていた。
特に図形も絵も張り付けているわけでもなくテキストのみでこのサイズはどう考えてもおかしい。
ちなみにフォーマット形式は XLSX なので圧縮が効いているはず。100K すら普通はいかないはずだ。

XLSX 形式であれば、中身を確認することが出来るので調べてみることにした。

拡張子を ZIP へ変更し、中身を解凍。
変な絵が張り付いていないことを確認して、問題のシート情報のファイルを確認する。
今回はシートは一つだけなので

./xl/worksheets/sheet1.xml

を確認してみると・・・・

80Mを超えている。

このファイル。普通にエディタで開こうとするとファイルサイズが大きいのでまともに開かない。
しょうがなく、ファイルを分割して中身を確認すると、入力したデータ以外に

<row r=”7609″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7609″ s=”16″/></row>
<row r=”7610″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7610″ s=”16″/></row>
<row r=”7611″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7611″ s=”16″/></row>
<row r=”7612″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7612″ s=”16″/></row>
<row r=”7613″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7613″ s=”16″/></row>
<row r=”7614″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C7614″ s=”16″/></row>

<row r=”1048575″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C1048575″ s=”16″/></row>
<row r=”1048576″ spans=”3:3″ x14ac:dyDescent=”0.15″><c r=”C1048576″ s=”16″/></row>

みたいなものが大量に書かれている。なんだこれ

 

想像してみる

データというわけではないので、セルに対しての属性情報が付与されていて、それが悪さをしているように感じる。
ただ、行の削除を行っても消すことが出来なかったので、行を選択した何かというよりはシート全体もしくは特定の列に仕掛けられた設定が生きているのだろう。

困った。

row タグは行データを取り扱っているとすると c タグが CELL を対象としていそう。
row タグ中の r 属性は行番号で、 spans 属性と x14ac:dyDescent 属性は謎だ。

c タグ中の r 属性は被るかもしれないが現在位置を表しているように見える
んー。cell の s 属性は 16 となっているのは何だろう。

 

調べてみた

dyDescent に関してはMS公式に説明が書いてあった。

http://msdn.microsoft.com/en-us/library/dd926776(v=office.12).aspx

要するに、double型の定義がされているということらしい。それだけ。ということは、x14ac のネームスペース中の定義として double と読むことが出来るのであれば、
x14ac はよくわからないけど Excel を意味するのではないだろうか。

と思ったら、ファイルの冒頭に

xmlns:x14ac=”http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac”

とあったので、大体理解があっていそう。

span 属性に関してはこちらに書いてあった

http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.row(v=office.14).aspx

要するに、データが入っている範囲を示すようで、この値はすべて同じになるようだ。
とすると、変だ。

現状では19行R列までデータが入っているので、

spans=”1:18″

になるはずなのだが。。。

 

ちなみに、シートのコピーではダメだったが新しく作ったブックにコピペしたら 22KB 程度のサイズになって、 spans も想定した値になった。

spans が変だったのは気になるのだが、それ以上に大量の row タグが作られてしまった原因のほうが問題なのだろう。

フォーマットの中身がなんとな~くわかってきたけれど、じゃ、どうすれば同じ状態を引き起こせるのか?という部分がさっぱりだ。
spans 属性の定義から言うと本来入る値とは異なっているので、ありていに言えば何かの操作の際にファイルがぶっ壊れたと考えたほうがいいのかもしれない。

うーん、壊れたのだとすると、これ以上追いかけてもあまり実りはないかな~。
とりあえず、少し調べ方に関して知ることが出来たので今日のところはよしとしようか

Softlayerを勉強してきた

以前のエントリで AWS をいじり始めたという話をしましたが、AWS だけでなく、Softlayer の研修も IBM で受けてきました。

会社では Microsoft の Windows Azure も利用している部署もあるのでより取り見取りですね。
私としては、これまでなんとなーく AWS が一番デファクト的な位置づけだと考えていたのですが、
単純にそれはその他を知らないだけという話でもあるかもしれないと考え、少し周りを調べ始めています。

AWS

AWS は言わずと知れたクラウドですね。

EC2 をはじめとして様々なサービスが提供されているので幅広い用途に使うことが出来ます。
個人的にはこのサービスの豊富さとその規模からくる価格メリット。そして成長・進化のスピードが AWS の強みに感じています。

まぁ、ろくに AWS を使っているわけではないので偉そうなことはあまりいうことは出来ませんが。

 

Softlayer

Softlayer は、もともとは独立したクラウドベンダーでしたが、IBM が現在は買収しています。
特徴的なのは、機器構成の自由度がかなりあるところです。

AWS で時々話があがるのは、インスタンスがどこに作られるかわからないので、同居しているインスタンスによってパフォーマンスに当たり外れがあるという話です。

Softlayer では、仮想ホストを共有する通常の形以外に、自分だけでホストを占有するタイプの仮想を選ぶことが出来ます。
(これをPrivateクラウドと呼ぶので混乱させているような気がしないでもない)
さらには、物理サーバーそのものを同じように Softlayer ポータルから借りることもできてしまいます

企業案件等でパフォーマンスがシビアに要求されるケースでは、ハイパーバイザーのオーバーヘッドを嫌がることもあると思います。
そういう意味では、Softlayer は自分たちで構成をゴリゴリと組みたいけどオンプレミスとして保持したくないというようなケースにおいては最適なのかもしれません。

もちろん、その場合のユーザー側の責任範囲は大きくなりますが。

一方で、サービス面に関しては AWS のほうが充実している印象を受けています。

クラウドで DB を利用しようとした場合、AWS であれば RDS を利用することが出来ます。
Softlayer ではバックアップを含めた運用管理は、よりオンプレミスに近い構築能力を要求されるとともに、Oracle 等を利用しようとした場合にはライセンスを用意する必要が出てしまいます。

クラウドの場合、やめようと思った時にやめられるのも利点ですが、こういったライセンスを時間貸しで利用できないのは、それが本来の形とはいえ辛いですね。
まぁ、MySQL や MongoDB 等のオープンソース系で行けばいいだけの話なのかもしれませんが。

AWS にしろ Softlayer にしろ、日々進化しているのである一時を切り出して優劣をつけていくのはなかなか難しい気もします。
ただ、それぞれの提供している特色というか特徴といったものがこの二つは分かれているので、すみわけは出来そう。

一方で、Microsoft の Azure は正直私が不勉強でよくわかっていないところが多いです。
どうなんだろうな

Surface Pro アクセサリ

今日は仕事の用事で一日外出。

いわゆる研修なのですが、ノートPCが必要になって手持ちのものがなかったのと、
特に業務で使用しているものでないといけない内容ではなかったのでSurfaceで研修を受けてきました。

これまで、ちょこちょこと使うことはあったのですが、長時間じっくりと触り続けたり
本当に仕事として使うことがあまりなかったのでちょっといろいろと新鮮でした。

PDFをリーダーアプリで開き、画面分割を調整しながらブラウザ操作をするという形でしたが、
思った以上になじんでつかことが出来ました。

やっぱりいろいろな使い方してみないとわからないものですね。

 

さて、Surfaceは普段100円均一で売っている保護ケースっぽいのに入れて持ち歩いているのですが、
普段移動中に持ち歩いているわけなのでもう少しちゃんとしたケースを買いたいところ。

ただ、ヨドバシとか行ってもそんなに種類がないんですよね。

いろいろ調べてみると、ケースだけでなく背面の保護にカーボンシートを張る人もいるみたいで、
Surface周辺のアクセサリをもう少し見直したほうが気持ちよく使えるかもしれないと考えています。

何かいいのないかな~