前回の
AWSを操作する──AWS::CLIWrapper
開発したサービスを運用するにあたっては、
その代わり、aws
コマンド)
なお、AWS_
にアクセスキーIDを、AWS_
にシークレットアクセスキーをセットしておきましょう。
EC2インスタンスの起動と終了
リスト1は、
use AWS::CLIWrapper;
# (1)AWS::CLIWrapperのオブジェクト生成
my $aws = AWS::CLIWrapper->new(
region => 'ap-northeast-1',
);
# (2)EC2インスタンスの起動
my $instance = $aws->ec2('run-instances' => {
# AMIのID
'image-id' => 'ami-xxxxxxxx',
# インスタンスのタイプ
'instance-type' => 't2.micro',
# インスタンスが属するサブネットのID
'subnet-id' => 'subnet-xxxxxxxx',
# インスタンスが属するセキュリティグループのID
'security-group-ids' => ['sg-xxxxxxxx'],
});
# (3)EC2インスタンスの終了
$aws->ec2('terminate-instances' => {
'instance-ids' => ['i-xxxxxxxx'],
});
まずリスト1 (1)では、region => 'ap-northeast-1'
を引数として与えることで東京リージョンを指定しています。リージョンは、AWS_
で設定することもできます。
リスト1 (2)では、ec2
メソッドを利用し、run-instances
を与えることで、$instance
で受け取っています。
なお、aws
コマンドのヘルプを参考にするとよいでしょう。
リスト1 (3)では、ec2
メソッドに対してterminate-instance
の操作を行うことで、instance-ids
で指定したインスタンスIDのEC2インスタンスを終了できます。
ELBの操作と確認
AWSを利用してEC2上にサービスを展開する場合、
use AWS::CLIWrapper;
my $aws = AWS::CLIWrapper->new(
region => 'ap-northeast-1'
);
# (1)EC2インスタンスをELBに登録
$aws->elb('register-instances-with-load-balancer', {
'load-balancer-name' => 'myapp-elb',
'instances' => ['i-xxxxxxxx'],
});
# (2)ヘルスチェックのステータス確認
# 3回繰り返す
my $retry = 3;
for my $i (1 .. $retry) {
# (3)ヘルスチェックのステータスを取得
my $states = $aws->elb(
'describe-instance-health', {
'load-balancer-name' => 'myapp-elb',
});
# (4)ステータスの確認
my $out_service = 0;
for my $instance (@{ $states->{InstanceStates} }) {
# ステータスの表示
printf("%s ... %s\n",
$instance->{InstanceId},
$instance->{State},
);
# (5)OutServiceのカウント
if ($instance->{InstanceId} ne 'InService') {
$out_service++
}
}
# すべてのインスタンスがInServiceの場合、
# ループを抜ける(成功)
last if $out_service == 0;
# (6)失敗時の処理
if ($i == $retry) {
warn "Failure!";
exit 1;
}
# 次のリトライまで一定時間待つ(ここでは10秒)
sleep 10;
}
リスト2 (1)では、load-balancer-name
で指定したmyapp-elb
という名前のELBに対して、instances
で指定したi-xxxxxxxx
というインスタンスIDのEC2インスタンスを登録しています。このとき、instances
は配列リファレンスの中に複数のインスタンスIDを指定することで、
ELBにEC2インスタンスを登録すると、InService
にならない限り、InService
になったかどうかを確認する必要があります。
リスト2 (2)は、InService
にならない場合もあるので、
次にヘルスチェックのステータスを確認するコードを詳しく見てみましょう。まずリスト2 (3)では、loadbalancer-name
でELBの名前を指定して、
そしてリスト2 (4)で、InService
、OutService
がインスタンスIDとともに表示されます。
万が一EC2インスタンスにデプロイされたアプリケーションにバグがあった場合など、InService
にならないこともあります。この場合、OutService
であるEC2インスタンスの数を計測し、
Mackerelを操作する──WebService::Mackerel
サービスを運用するにあたり、
ホストの取得
リスト3は、
use WebService::Mackerel;
use JSON;
# (1)WebService::Mackerelのオブジェクト生成
my $mkr = WebService::Mackerel->new(
api_key => 'key',
service_name => 'service',
);
# (2)ホスト一覧の取得
my $response = decode_json( $mkr->get_hosts );
my $hosts = $response->{hosts};
# (3)ホスト名の表示
for my $host (@{ $hosts }) {
printf "%s\n", $host->{name};
}
リスト3 (1)では、api_
というパラメータとして与える必要がありますので、service_
というパラメータとして与える必要があります。
リスト3 (2)では、get_
メソッドを利用して、
最後にリスト3 (3)では、
ちなみに筆者は、
App 10.0.xxx.xxx (instance-size) ... working 10.0.xxx.xxx (instance-size) ... working Worker 10.0.xxx.xxx (instance-size) ... working 10.0.xxx.xxx (instance-size) ... working
監視パラメータの取得と変更
Mackerelには監視パラメータの変更APIがあり、
リスト4は、get_
メソッドで取得できます。
use WebService::Mackerel;
use JSON;
use Data::Dumper;
my $mkr = WebService::Mackerel->new(
api_key => 'key',
service_name => 'service',
);
# 監視パラメータの取得
my $payload = decode_json( $mkr->get_monitor );
my $monitors = $payload->{monitors};
# 監視パラメータの表示
print Dumper $monitors;
このコードを実行すると、connectivity
host
に対するcpu%
cpu%
については、warning
が50%で、critical
が80%でそれぞれアラートが通知されることなどがわかります。
$VAR1 = [ { 'scopes' => [], 'excludeScopes' => [], 'id' => 'xxxxxxxxxxx', 'type' => 'connectivity' }, { 'operator' => '>', 'name' => 'CPU %', 'metric' => 'cpu%', 'warning' => '50', 'type' => 'host', 'id' => 'yyyyyyyyyyy', 'duration' => 1, 'excludeScopes' => [], 'critical' => '80', 'scopes' => [] },
さらに、update_
メソッドで行い、cpu%
のアラート通知条件をwarning
は60%、critical
は90%にそれぞれ変更しています。
use WebService::Mackerel;
use JSON;
use Data::Dumper;
my $mkr = WebService::Mackerel->new(
api_key => 'key',
service_name => 'service',
);
# (1)監視パラメータの更新
$mkr->update_monitor('yyyyyyyyyyy', {
type => "host",
name => "CPU %",
metric => "cpu%",
duration => 1,
operator => ">",
warning => 60,
critical => 90,
scopes => [],
excludeScopes => [],
});
<続きの