AWS CLIを利用して、CloudWatch EventsでEBSスナップショットを取得してみます。
注) このハンズオンはコンプリートできないことがわかってます。後日更新予定です。
前提条件
CloudWatch Eventsへの権限
CloudWatchEventsに対してフル権限があること。
EC2への権限
EBSに対してフル権限があること。
AWS CLIのバージョン
以下のバージョンで動作確認済
- AWS CLI 1.10.4
コマンド
aws --version
結果(例)
aws-cli/1.10.4 Python/2.7.5 Darwin/13.4.0 botocore/1.3.26
IAMロール
'AWSEventsActionsExecutionRole'ロールが存在すること。
変数の設定
IAM_ROLE_NAME='AWSEventsActionsExecutionRole'
コマンド
aws iam get-role \
--role-name ${IAM_ROLE_NAME}
結果(例)
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "automation.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
},
"RoleId": "AROAXXXXXXXXXXXXXXXXX",
"CreateDate": "2016-02-15T04:38:43Z",
"RoleName": "AWSEventsActionsExecutionRole",
"Path": "/",
"Arn": "arn:aws:iam::XXXXXXXXXXXX:role/AWSEventsActionsExecutionRole"
}
}
- 準備
=======
0.1. リージョンの決定
構築するリージョンを決めます。 (カレントユーザが利用するカレントリージ
ョンも切り変わります。)
コマンド(東京リージョンの場合)
export AWS_DEFAULT_REGION='ap-northeast-1'
0.2. 変数の確認
プロファイルが想定のものになっていることを確認します。
コマンド
aws configure list
結果(例)
Name Value Type Location
---- ----- ---- --------
profile administrator-prjZ-mbp13 env AWS_DEFAULT_PROFILE
access_key ****************XXXX shared-credentials-file
secret_key ****************XXXX shared-credentials-file
region ap-northeast-1 env AWS_DEFAULT_REGION
0.3. IAM RoleのARN取得
コマンド
IAM_ROLE_ARN=$( \
aws iam get-role \
--role-name ${IAM_ROLE_NAME} \
--query 'Role.Arn' \
--output text \
) \
&& echo ${IAM_ROLE_ARN}
結果(例)
arn:aws:iam::XXXXXXXXXXXX:role/AWSEventsActionsExecutionRole'
- 事前作業
===========
1.1. EBSボリュームの確認
コマンド
aws ec2 describe-volumes
結果(例)
{
"Volumes": [
{
"AvailabilityZone": "ap-northeast-1a",
"Attachments": [],
"Encrypted": false,
"VolumeType": "standard",
"VolumeId": "vol-xxxxxxxx",
"State": "available",
"SnapshotId": "",
"CreateTime": "2016-02-15T04:01:51.884Z",
"Size": 5
}
]
}
1.2. EBSボリュームの作成
ボリュームが存在しない場合は、作成します。
作成できるAZを調べます。
コマンド
aws ec2 describe-availability-zones
結果(例)
{
"AvailabilityZones": [
{
"State": "available",
"RegionName": "ap-northeast-1",
"Messages": [],
"ZoneName": "ap-northeast-1a"
},
{
"State": "available",
"RegionName": "ap-northeast-1",
"Messages": [],
"ZoneName": "ap-northeast-1c"
}
]
}
変数の設定
EC2_AZ_NAME='ap-northeast-1a'
EC2_IMAGE_SIZE='5'
変数の確認
cat << ETX
EC2_AZ_NAME: ${EC2_AZ_NAME}
EC2_IMAGE_SIZE: ${EC2_IMAGE_SIZE}
ETX
コマンド
aws ec2 create-volume \
--availability-zone ${EC2_AZ_NAME} \
--size ${EC2_IMAGE_SIZE}
結果(例)
{
"AvailabilityZone": "ap-northeast-1a",
"Encrypted": false,
"VolumeType": "standard",
"VolumeId": "vol-xxxxxxxx",
"State": "creating",
"SnapshotId": "",
"CreateTime": "2016-02-15T04:01:51.884Z",
"Size": 5
}
1.3. EBS Volume IDの取得
変数の設定
EC2_VOLUME_ID=$( \
aws ec2 describe-volumes \
--query "Volumes[?State==\`available\` && AvailabilityZone==\`${EC2_AZ_NAME}\`]".VolumeId \
--output text
) && echo ${EC2_VOLUME_ID}
変数の設定
TARGET_AWS_SERVICE='ec2'
TARGET_RESOURCE='volume'
- ルールの作成
===============
2.1. ルール名の指定
変数の設定
EVENTS_RULE_NAME='create-ebs-snapshot'
同名のルールが存在しないことを確認します。
コマンド
aws events describe-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
A client error (ResourceNotFoundException) occurred when calling the DescribeRule operation: Rule create-ebs-snapshot does not exist.
2.1. ルールの作成
変数の設定
EVENTS_RULE_DESC='Create ebs snapshot.'
EVENTS_RULE_STATE='DISABLED'
EVENTS_SCHE_EXPRESSION='rate(5 minutes)'
変数の設定
FILE_INPUT="${EVENTS_RULE_NAME}.json" \
&& echo ${FILE_INPUT}
変数の確認
cat << ETX
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
EVENTS_RULE_DESC: "${EVENTS_RULE_DESC}"
EVENTS_RULE_STATE: ${EVENTS_RULE_STATE}
EVENTS_SCHE_EXPRESSION: ${EVENTS_SCHE_EXPRESSION}
FILE_INPUT: ${FILE_INPUT}
IAM_ROLE_ARN: ${IAM_ROLE_ARN}
}
ETX
コマンド
cat << EOF > ${FILE_INPUT}
{
"Name": "${EVENTS_RULE_NAME}",
"ScheduleExpression": "${EVENTS_SCHE_EXPRESSION}",
"State": "${EVENTS_RULE_STATE}",
"Description": "${EVENTS_RULE_DESC}",
"RoleArn": "${IAM_ROLE_ARN}"
}
EOF
cat ${FILE_INPUT}
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
コマンド
jsonlint -q ${FILE_INPUT}
エラーが出力されなければOKです。
変数の確認
cat << ETX
FILE_INPUT: ${FILE_INPUT}
ETX
コマンド(cli-input-json)
aws events put-rule \
--cli-input-json file://${FILE_INPUT}
結果(例)
{
"RuleArn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/create-ebs-snapshot"
}
2.2. ルールの確認
コマンド
aws events list-rules
結果(例)
{
"Rules": []
}
コマンド
aws events list-rules
結果(例)
{
"Rules": [
{
"State": "DISABLED",
"ScheduleExpression": "rate(5 minutes)",
"Name": "|EVENTS_RULE_NAME|",
"Arn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/create-ebs-snapshot",
"Description": "Create ebs snapshot."
}
]
}
コマンド
aws events describe-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
{
"ScheduleExpression": "rate(5 minutes)",
"Name": "create-ebs-snapshot",
"State": "DISABLED",
"Arn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/create-ebs-snapshot",
"Description": "create-ebs-snapshot"
}
- ターゲットの作成
===================
3.1. ターゲットIDの指定
変数の設定
EVENTS_TARGET_ID='Id1'
同Idのターゲット名が存在しないことを確認します。
コマンド
aws events list-targets-by-rule \
--rule ${EVENTS_RULE_NAME} \
--query "Targets[?Id==\`${EVENTS_TARGET_ID}\`]"
結果(例)
[]
3.2. ターゲットの作成
コマンド
AWS_ID=$( \
aws iam get-role \
--role-name ${IAM_ROLE_NAME} \
--query 'Role.Arn' \
--output text | \
sed 's/^.*:://' | \
sed 's/:.*$//' \
) \
&& echo ${AWS_ID}
結果(例)
XXXXXXXXXXXX
変数の確認
cat << ETX
AWS_ID: ${AWS_ID}
TARGET_AWS_SERVICE: ${TARGET_AWS_SERVICE}
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
TARGET_RESOURCE: ${TARGET_RESOURCE}
EC2_VOLUME_ID: ${EC2_VOLUME_ID}
ETX
変数の設定
EVENTS_TARGET_INPUT="arn:aws:${TARGET_AWS_SERVICE}:${AWS_DEFAULT_REGION}:${AWS_ID}:${TARGET_RESOURCE}/${EC2_VOLUME_ID}" \
&& echo ${EVENTS_TARGET_INPUT}
変数の設定
EVENTS_TARGET_ARN="arn:aws:automation:${AWS_DEFAULT_REGION}:${AWS_ID}:action/EBSCreateSnapshot/EBSCreateSnapshot_create-ebs-snapshot" \
&& echo ${EVENTS_TARGET_ARN}
変数の設定
FILE_INPUT="${EVENTS_RULE_NAME}-${EVENTS_TARGET_ID}.json" \
&& echo ${FILE_INPUT}
変数の確認
cat << ETX
FILE_INPUT: ${FILE_INPUT}
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
EVENTS_TARGET_ID: ${EVENTS_TARGET_ID}
EVENTS_TARGET_INPUT: ${EVENTS_TARGET_INPUT}
EVENTS_TARGET_ARN: ${EVENTS_TARGET_ARN}
ETX
コマンド
cat << EOF > ${FILE_INPUT}
{
"Rule": "${EVENTS_RULE_NAME}",
"Targets": [
{
"Input": "\"${EVENTS_TARGET_INPUT}\"",
"Id": "${EVENTS_TARGET_ID}",
"Arn": "${EVENTS_TARGET_ARN}"
}
]
}
EOF
cat ${FILE_INPUT}
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
コマンド
jsonlint -q ${FILE_INPUT}
エラーが出力されなければOKです。
変数の確認
cat << ETX
FILE_INPUT: ${FILE_INPUT}
ETX
コマンド(cli-input-json)
aws events put-targets \
--cli-input-json file://${FILE_INPUT}
結果(例)
{
"FailedEntries": [],
"FailedEntryCount": 0
}
3.3. ターゲットの確認
コマンド
aws events list-targets-by-rule \
--rule ${EVENTS_RULE_NAME}
結果(例)
{
"Targets": [
{
"Input": ""arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:volume/vol-xxxxxxxx"",
"Id": "Id1",
"Arn": "arn:aws:automation:ap-northeast-1:XXXXXXXXXXXX:action/EBSCreateSnapshot/EBSCreateSnapshot_test"
}
]
}
コマンド
aws events list-rule-names-by-target \
--target-arn ${EVENTS_TARGET_ARN}
結果(例)
{
"RuleNames": [
"create-ebs-snapshot"
]
}
- ルールの有効化/無効化
========================
4.1. ルールの有効化
コマンド
aws ec2 describe-snapshots \
--owner-ids ${AWS_ID}
結果(例)
{
"Snapshots": []
}
変数の確認
cat << ETX
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
ETX
コマンド
aws events enable-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
(戻り値なし)
コマンド
aws ec2 describe-snapshots \
--owner-ids ${AWS_ID}
結果(例)
{
"Snapshots": []
}
4.2. ルールの無効化
変数の確認
cat << ETX
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
ETX
コマンド
aws events disable-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
(戻り値なし)
- 後始末
=========
5.1. スナップショットの削除
変数の宣言
EC2_SNAPSHOT_ID=$( \
aws ec2 describe-snapshots \
--owner-ids ${AWS_ID} \
--query "Snapshots[?VolumeId==\`${EC2_VOLUME_ID}\`].SnapshotId" \
--output text \
) && echo ${EC2_SNAPSHOT_ID}
コマンド
aws ec2 delete-snapshot \
--snapshot-id ${EC2_SNAPSHOT_ID}
結果(例)
(戻り値なし)
変数の宣言
EC2_SNAPSHOT_ID=$( \
aws ec2 describe-snapshots \
--owner-ids ${AWS_ID} \
--query "Snapshots[?VolumeId==\`${EC2_VOLUME_ID}\`].SnapshotId" \
--output text \
) && echo ${EC2_SNAPSHOT_ID}
結果(例)
(戻り値なし)
5.2. EBSボリュームの削除
コマンド
aws ec2 describe-volumes \
--volume-ids ${EC2_VOLUME_ID}
結果(例)
{
"Volumes": [
{
"AvailabilityZone": "ap-northeast-1a",
"Attachments": [],
"Encrypted": false,
"VolumeType": "standard",
"VolumeId": "vol-xxxxxxxx",
"State": "available",
"SnapshotId": "",
"CreateTime": "2016-02-15T04:01:51.884Z",
"Size": 5
}
]
}
コマンド
aws ec2 delete-volume \
--volume-id ${EC2_VOLUME_ID}
結果(例)
(戻り値なし)
コマンド
aws ec2 describe-volumes \
--volume-ids ${EC2_VOLUME_ID}
結果(例)
A client error (InvalidVolume.NotFound) occurred when calling the DescribeVolumes operation: The volume 'vol-xxxxxxxx' does not exist.
5.3. ターゲットの削除
コマンド
aws events list-targets-by-rule \
--rule ${EVENTS_RULE_NAME} \
--query "Targets[?Id==\`${EVENTS_TARGET_ID}\`]"
結果(例)
[
{
"Input": "\"arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:volume/vol-xxxxxxxx\"",
"Id": "Id1",
"Arn": "arn:aws:automation:ap-northeast-1:XXXXXXXXXXXX:action/EBSCreateSnapshot/EBSCreateSnapshot_create-ebs-snapshot"
}
]
変数の設定
ARRAY_EVENTS_TARGET_IDS="${EVENTS_TARGET_ID}"
変数の確認
cat << ETX
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
ARRAY_EVENTS_TARGET_IDS: "${ARRAY_EVENTS_TARGET_IDS}"
ETX
コマンド
aws events remove-targets \
--rule ${EVENTS_RULE_NAME} \
--ids "${ARRAY_EVENTS_TARGET_IDS}"
結果(例)
{
"FailedEntries": [],
"FailedEntryCount": 0
}
コマンド
aws events list-targets-by-rule \
--rule ${EVENTS_RULE_NAME}
結果(例)
{
"Targets": []
}
5.4. ルールの削除
コマンド
aws events describe-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
{
"ScheduleExpression": "rate(5 minutes)",
"Name": "create-ebs-snapshot",
"State": "DISABLED",
"Arn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/create-ebs-snapshot",
"Description": "create-ebs-snapshot"
}
変数の確認
cat << ETX
EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
ETX
コマンド
aws events delete-rule \
--name ${EVENTS_RULE_NAME}
結果(例)
(戻り値なし)