aws-cliからCloudFormationを使う

CloudFormationを使うにはテンプレートファイルが必要になるのだが、今回は、AWSが提供しているテンプレートをローカルに持ってきて使う。

ローカルのテンプレートファイルを指定してスタックを作成するには以下のコマンドを実行する。

$ aws cloudformation create-stack \
  --stack-name sample \
  --template-body file:///home/nowtom/sample.template \
  --parameters ParameterKey=KeyName,ParameterValue=sample-keypair \
               ParameterKey=VpcId,ParameterValue=vpc-xxxxxxxx \
               ParameterKey=SubnetId,ParameterValue=subnet-xxxxxxxx
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/sample/95338e20-5af8-11e3-9c5c-506cf9a1c096"
}


スタックの状態を確認するには、以下のコマンドを実行する。

$ aws cloudformation describe-stacks --stack-name sample

スタックが作成中だとStackStatusがCREATE_IN_PROGRESSになっていて、問題なければそのうちCREATE_COMPLETEになる。


状態がROLLBACK_IN_PROGRESSとかになって、スタックの作成が失敗した場合は以下のコマンドで理由が調べられる。
ResourceStatusReasonに失敗した理由が格納されている。
マネジメントコンソールから見えない場合も、コマンドからなら見える場合がある。

$ aws cloudformation describe-stack-events --stack-name sample


スタックを削除するには、以下のコマンドを実行する。
忘れずに消さないと課金される。

$ aws cloudformation delete-stack --stack-name sample

StorageGatewayとEBSボリュームのマッピングを調べる

StorageGatewayにつけているEBSで、どれがCacheでどれがUpload Bufferなのかわからなくなってしまった。
マネジメントコンソールからはわからなかったので、aws-cliで調べてみた。


まずは、StorageGatewayの特定をする。
以下のコマンドでStorageGatewayの一覧が取得できる。

$ aws storagegateway list-gateways
{
    "Gateways": [
        {
            "GatewayARN": "arn:aws:storagegateway:ap-northeast-1:xxxxxxxxxxxx:gateway/xxxxx", 
            "GatewayOperationalState": "ACTIVE", 
            "GatewayType": "CACHED"
        }
    ]
}

StorageGatewayの特定ができたので、以下のコマンドでローカルディスクの一覧を取得する。
aws-cliからStorageGatewayを操作する場合、GatewayIdではなく、GatewayARNを使うらしい。

$ aws storagegateway list-local-disks --gateway-arn arn:aws:storagegateway:ap-northeast-1:xxxxxxxxxxxx:gateway/xxxxx
{
    "GatewayARN": "arn:aws:storagegateway:ap-northeast-1:xxxxxxxxxxxx:gateway/xxxxx", 
    "Disks": [
        {
            "DiskPath": "/dev/xvdk", 
            "DiskNode": "xen-vbd-2208", 
            "DiskSizeInBytes": 268435456000, 
            "DiskId": "xen-vbd-2208", 
            "DiskAllocationType": "CACHE STORAGE"
        }, 
        {
            "DiskPath": "/dev/xvdj", 
            "DiskNode": "xen-vbd-2192", 
            "DiskSizeInBytes": 268435456000, 
            "DiskId": "xen-vbd-2192", 
            "DiskAllocationType": "CACHE STORAGE"
        }, 
        {
            "DiskPath": "/dev/xvdi", 
            "DiskNode": "xen-vbd-2176", 
            "DiskSizeInBytes": 429496729600, 
            "DiskId": "xen-vbd-2176", 
            "DiskAllocationType": "CACHE STORAGE"
        }, 
        {
            "DiskPath": "/dev/xvdg", 
            "DiskNode": "xen-vbd-2144", 
            "DiskSizeInBytes": 107374182400, 
            "DiskId": "xen-vbd-2144", 
            "DiskAllocationType": "UPLOAD BUFFER"
        }, 
        {
            "DiskPath": "/dev/xvdh", 
            "DiskNode": "xen-vbd-2160", 
            "DiskSizeInBytes": 107374182400, 
            "DiskId": "xen-vbd-2160", 
            "DiskAllocationType": "CACHE STORAGE"
        }
    ]
}

DiskPathとDiskAllocationTypeでどのEBSをなにに使っているのかわかった。
ちゃんとNameタグをつけておこう・・・。

CloudWatchからメトリクスを取得する

AWS Storage Gatewayを読んで、
aws-cli経由でStorageGatewayのメトリクスの取り方を調べてみた。

作業内容

まずは、StorageGatewayのメトリクス一覧を取得する。

$ aws cloudwatch list-metrics --namespace AWS/StorageGateway
多いので省略

試しにCacheHitPercentを取るために、--metric-nameを指定して絞り込む。

$ aws cloudwatch list-metrics --namespace AWS/StorageGateway --metric-name CacheHitPercent
{
    "Metrics": [
        {
            "Namespace": "AWS/StorageGateway", 
            "Dimensions": [
                {
                    "Name": "GatewayId", 
                    "Value": "sgw-xxxxxxxx"
                }, 
                {
                    "Name": "GatewayName", 
                    "Value": "xxxxx"
                }
            ], 
            "MetricName": "CacheHitPercent"
        }, 
        {
            "Namespace": "AWS/StorageGateway", 
            "Dimensions": [
                {
                    "Name": "VolumeId", 
                    "Value": "ap-northeast-1-vol-xxxxxxxx"
                }
            ], 
            "MetricName": "CacheHitPercent"
        }
    ]
}

すると、StorageGateway全体とボリュームごとのメトリクスがでてきた。
今回取りたいのは、StorageGateway全体のCacheHitPercentなので、以下のようにしてメトリクス値を取る。

$ aws cloudwatch get-metric-statistics \
                            --namespace AWS/StorageGateway \
                            --metric-name CacheHitPercent \
                            --dimensions Name=GatewayId,Value=sgw-xxxxxxxx Name=GatewayName,Value=xxxxx \
                            --statistics Average \
                            --period 300 \
                            --start-time `date -u -d '9 minutes ago' +%Y-%m-%dT%TZ` \
                            --end-time `date -u +%Y-%m-%dT%TZ`
{
    "Datapoints": [
        {
            "Timestamp": "2013-11-21T16:00:00Z", 
            "Average": 15.932732316227463, 
            "Unit": "Percent"
        }
    ], 
    "Label": "CacheHitPercent"
}

ポイントは、--dimensionsで、GatewayIdとGatewayNameを指定すること。
片方だけの指定だとメトリクス値が空になってしまう。
また、--start-timeも5分前の指定だと空になってしまう場合があったので、9分前にした。

以下のようにするとメトリクス値のみ取得できる。

$ aws cloudwatch get-metric-statistics \
                            --namespace AWS/StorageGateway \
                            --metric-name CacheHitPercent \
                            --dimensions Name=GatewayId,Value=sgw-xxxxxxxx Name=GatewayName,Value=xxxxx \
                            --statistics Average \
                            --period 300 \
                            --start-time `date -u -d '9 minutes ago' +%Y-%m-%dT%TZ` \
                            --end-time `date -u +%Y-%m-%dT%TZ` \
                            --query "Datapoints.[0].Average"
15.932732316227463

--queryは、JMESPath(ジェームズパス)という記法で書くらしい。
--queryを使わない場合は、jqでも同じことができる。

最終的にはこの値を定期的にzabbixに入れてグラフ化するところまでやってみたい。

CentOSにaws-cliをインストールする

ローカルのCentOSaws-cliを入れてみた。

作業内容

yumにepelリポジトリを登録する

$ sudo rpm -ivh http://mirror-fpt-telecom.fpt.net/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

awscliをインストールするのに必要な、python-develとpython-pipをインストールする

$ sudo yum install python-devel python-pip

pipを使ってaws-cliをインストールする

$ sudo pip install awscli

aws-cliの設定ファイルを作成する

$ mkdir -p ~/.aws
$ vi ~/.aws/config
[default]
aws_access_key_id=
aws_secret_access_key=
region=ap-northeast-1

試しにリージョンを取得してみる

$ aws ec2 describe-regions

zshの補完機能を使えるようにする

$ vi ~/.zshrc
source /usr/bin/aws_zsh_completer.sh

RailsのJSONをExtJS4のExt.grid.panelで読み込む

RailsにExtJS4を乗せてみて、ちょっとはまったことをメモ。

Rails

Userモデルに、nameとageを持たせてるとする。
そして、UserをJSONで全件返すコントローラを作成したとする。

class TweetsController < ApplicationController
  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
      format.json  { render :json => @users }
    end
  end
end

http://localhost:3000/users.jsonのような感じでアクセスすると下記のJSONが返ってくる。

[
  {"user":{"name":"_ryog","created_at":"2011-07-28T08:33:01Z","id":1,"updated_at":"2011-07-28T08:33:01Z","age":"24"}},
  {"user":{"name":"mr_k_o","created_at":"2011-07-28T08:36:33Z","id":2,"updated_at":"2011-07-28T08:36:33Z","age":"30"}}
]

ExtJS

Ext.grid.PanelにExt.data.Storeを設定して、上記のJSONを表示させたいんだけど、こんな感じでいけるかなと思ったらだめだった。
Panel

Ext.define('Sample.view.User' ,{
  extend: 'Ext.grid.Panel',
  alias : 'widget.users',

  title : 'ユーザ一覧',
  store: 'Users',

  initComponent: function() {
    this.columns = [
      {header: '名前', dataIndex: 'name', flex: 1},
      {header: '年齢', dataIndex: 'age', flex: 1}
    ];
    this.callParent(arguments);
  }
});

Model

Ext.define('Sample.model.User', {
  extend: 'Ext.data.Model',
  fields: ['name', 'age']
});

Store

Ext.define('Sample.store.Users', {
  extend: 'Ext.data.Store',
  model: 'Sample.model.User',
  autoLoad: true,

  proxy: {
    type: 'ajax',
    api: {
      read: 'http://localhost:3000/users.json'
    }, 
    reader: {
      type: 'json',
      root: '',
      successProperty: 'success'
    }
  }
});

readerのtypeにjsonとあるから、そういうクラスがあるのかと思って探してみたら、Ext.data.reader.Jsonがあった。
ドキュメント読んでみたら、recordを設定しろと。
Store

Ext.define('Sample.store.Users', {
  extend: 'Ext.data.Store',
  model: 'Sample.model.User',
  autoLoad: true,

  proxy: {
    type: 'ajax',
    api: {
      read: 'http://localhost:3000/users.json'
    }, 
    reader: {
      type: 'json',
      root: '',
      record: 'user',
      successProperty: 'success'
    }
  }
});

でましたぁ〜。あー、すっきり。

追記

こんなサンプルコードを書いてる人がいた。
素晴らしい。

Mac+HomeBrew+Postgresql+pg

MacPostgresqlを使おうとしてはまったことをメモ。

Posgtgresqlのインストール

HomeBrewを導入しているのでインストール自体は下記のコマンドで一発。

$ brew install postgresql

Postgresqlの初期設定

データベースの初期化をする

$ initdb /usr/local/var/postgres

Postgresqlの起動と終了

まずは起動。

pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

次に終了。

pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

自動で起動する場合は、下記のコマンドを実行する。

$ launchctl unload -w ~/Library/LaunchAgents/org.postgresql.postgres.plist
$ cp /usr/local/Cellar/postgresql/9.0.4/org.postgresql.postgres.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist

ユーザの作成

Railsアプリ用のDB接続ユーザを作成する

$ createuser -P app_name
# パスワードとスーパーユーザにするかどうかを入力する

確認は下記のコマンドでできる。

psql -q -c'select * from pg_user' postgres

Postgresqlに接続するためのRubyGemsのpgをインストールする

ここでインストール方法を間違ってはまった。
単純に「gem install pg」ではだめ。
rake db:createとかやると「Permission Denied」で怒られる。

調べたらHomeBrewがご丁寧に説明をしてくれるらしい。

$ brew info postgresql
# 抜粋
If you want to install the postgres gem, including ARCHFLAGS is recommended:
    env ARCHFLAGS="-arch x86_64" gem install pg

これだよorz

これをこのまま実行する。

$ env ARCHFLAGS="-arch x86_64" gem install pg

rake通ったぁ・・・。

ちなみに、bundlerの場合どうするんだろう?

UbuntuとMacでのコマンドの違い

UbuntuからMacに移行したら、lsコマンドが動かなくなっていた。
原因は下記のエイリアスを使っていたためだった。

ls='ls --color'

下記のように修正したら動いた。

ls='ls -G'

参考サイト