この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんばんは、城内です。 ついに先日AWS LambdaがTokyoリージョンに上陸しましたね。以下のまとめ記事、いいですね!
そんな中、今回はData Pipelineネタです。なぜいまLambdaのTokyoリージョン上陸を喜びつつもData Pipelineなのかは、この記事をご覧頂ければきっと分かってもらえるかと思います(笑)。
はじめに
今回何をやるのかというと、Data Pipelineをジョブスケジューラ代わりに使ってみたいと思います。 実行する処理は、定期的に不要なEC2インスタンスを停止するジョブです。開発用インスタンスの止め忘れなど、皆さんもよくあることかと思います。
事前準備
まず、Data Pipelineのロジック部分となるスクリプトとそれを格納するS3バケット、通知用のSNSトピックを作成します。
EC2インスタンス停止スクリプト
今回は以下のようなスクリプトを作成しました。 基本は、対象リージョンで起動しているすべてのEC2インスタンスを容赦なく停止していく仕様なのですが、除外の措置として、停止したくないEC2インスタンスに対し、「Production=True」タグを設定しておけば対象外となります。
stop-instances.sh
#!/bin/bash
targetRegion="ap-northeast-1"
myTagName="Production"
timeoutMins=5
topicArn="arn:aws:sns:ap-northeast-1:123456789012:dp-test"
export AWS_DEFAULT_REGION=$targetRegion
prodInstanceIds=$(echo $(aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(.Tags[] | select(.Key == "'$myTagName'") | .Value == "True").InstanceId'))
myInstanceId=$(curl -s http://169.254.169.254/latest/meta-data/instance-id/)
nonStopInstanceIds="$myInstanceId $prodInstanceIds"
stopInstanceIds=
for runInstanceId in $(aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(.State.Name == "running").InstanceId')
do
runInstanceId=$(echo $runInstanceId | sed 's/\"//g')
if [ $(echo $nonStopInstanceIds | grep -c $runInstanceId) -eq 0 ]; then
aws ec2 stop-instances --instance-ids $runInstanceId
if [ "$stopInstanceIds" == "" ]; then
stopInstanceIds="$runInstanceId"
else
stopInstanceIds="${stopInstanceIds} $runInstanceId"
fi
fi
done
if [ "$stopInstanceIds" == "" ]; then
exit 0
fi
notStopInstanceIds=$stopInstanceIds
for ((i=0; i < $timeoutMins; i++)); do
sleep 60
for checkInstanceId in $stopInstanceIds
do
result=$(aws ec2 describe-instance-status --instance-ids $checkInstanceId | jq '.InstanceStatuses[]')
if [ "$result" == "" ]; then
notStopInstanceIds=$(echo $notStopInstanceIds | sed "s/$checkInstanceId//")
fi
done
if [ "$(echo $notStopInstanceIds | sed 's/ //g')" == "" ]; then
break
fi
done
stopInstanceIds=$(echo -e $(echo $stopInstanceIds | sed 's/ /\\n・/g'))
notStopInstanceIds=$(echo $notStopInstanceIds | sed 's/ /、/g')
message="以下のインスタンスを停止しました。
・$stopInstanceIds"
if [ "$notStopInstanceIds" != "" ]; then
message="$message
※${notStopInstanceIds}のインスタンスは停止できませんでした。"
fi
aws sns publish --topic-arn $topicArn --message "$message" --subject "[Information] Job Scheduler has stopped EC2 instances."
exit 0
S3バケットの作成
以下のようにS3バケットを作成し、配下に上記のスクリプト格納用フォルダ(script)と、ついでにログ格納用のフォルダ(log)も作成します。
そして、上記のスクリプトをscriptフォルダにアップロードしておきます。
SNSトピックの作成
上記のスクリプトの中で、結果通知用にSNSを送信しているので、そのためのSNSトピックを作成します。ちなみに、今回はData Pipelineでの通知設定は省略しています。
Data Pipelineセットアップ
では、さっそくData Pipelineの設定に入ります。
Create new pipeline
Data Pipelineのマネージメントコンソールを開き、[Create new pipeline]をクリックします。 以下の画面で、とりあえず赤枠の部分を設定しています。この後の画面で構成を設定するので、「Source」は「Build using Architect」を選択し、ログも事前に作成したS3バケットのフォルダに出力するようにします。
Edit in Architect
次に、構成を設定します。が、今回はShellCommandActivityを1つ作成するだけです。 以下のような感じで、とりあえず最低限の項目を設定します。
Schedulesは以下の通りです。
ResourcecsはEC2を使用します。
Preconditionsとして、jqのインストールを実行します。
Othersはデフォルトのままです。
ポリシーの変更
上記のData Pipelineをアクティブにする前に、スクリプトの実行でちゃんとEC2を停止できるよう、デフォルトのポリシー(DataPipelineDefaultResourceRole)を変更します。
DataPipelineDefaultResourceRole
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"ec2:*",
"elasticmapreduce:Describe*",
"elasticmapreduce:ListInstance*",
"elasticmapreduce:AddJobFlowSteps",
"rds:Describe*",
"datapipeline:*",
"cloudwatch:*",
"redshift:DescribeClusters",
"redshift:DescribeClusterSecurityGroups",
"sdb:*",
"sns:*",
"sqs:*"
],
"Resource": [
"*"
]
}
]
}
動作確認
最後に、動作確認をしてみます。動作確認のために、以下のようテストインスタンスを3つ立ち上げます。
- Test Server Stg ... Production=False
- Test Server Prod ... Production=True
- Test Server Dev ... Productionタグなし
作成したData Pipelineをアクティブにすると、まず実行環境となるEC2が立ち上がります。
そして、指定した時間になると、実行環境のEC2上でスクリプトが実行され、「Production=True」のタグがついていないEC2インスタンスが停止されます。
役目を終えた実行環境のEC2は、実行後に削除されます。
Data Pipelineの実行結果は以下の通りです。
ちゃんと結果通知メールも届いています。
さいごに
いかがでしょうか?Data Pipelineに少しでも興味を持って頂けたなら光栄です。
では、なぜLambdaフィーバー時にData Pipelineかと言えば、その理由は以下のスライドをご覧ください。 読み終えた時には、きっとData Pipelineを試してみたくなりますよ!
[slideshare id=42220749&doc=20141126aws-blackbelt-datapipeline-public-141201095140-conversion-gate01&w=640&h=320]