AWS CLIの処理をAWS Data Pipelineで自動化する
先日投稿した以下のAWS Data Pipeline関連エントリで、サービスを構成する諸要素のおおまかな内容が把握出来ました。当エントリ(以降)では実際に予め用意されているテンプレート等を使って実際の利用シーンを想定したパイプラインの作成について見て行きたいと思います。
まず初っ端1本目は『AWS CLIの処理をAWS Data Pipelineで実行する』というテーマから。
目次
AWS Data Pipeline 構成イメージ
AWS CLI(AWS Command Line Interface)はAWSに於ける諸々のサービスに関する操作をコマンドラインベースで行えるユーティリティツールです。任意の環境からオプション等を組み合わせる事で、自在にAWSの各種操作を効率化・自動化する事が出来ます。
従来の利用方法であれば、このAWS CLIを適宜手動で実施、または稼働OS環境上で何らかのスクリプト言語を介してAWS CLIを実行すると言うような形がまず先に浮かぶのではと思われます。今回はこの"稼働OS環境"の部分がAWS Data Pipelineからの指示として置き換わる様なイメージです。画にするとこんな感じでしょうか。ちなみに今回はごくごくシンプルな『EC2インスタンスの起動・停止』を例にして進めてみたいと思います。任意の時間にそれぞれ起動・停止に相当するAWS CLIが実行されるイメージです。
コードに書き起こすとこのような形になります。
# AWS CLI: インスタンスの起動 aws ec2 start-instances --instance-ids i-xxxxxxxx # AWS CLI: インスタンスの停止 aws ec2 stop-instances --instance-ids i-xxxxxxxx
AWS Data Pipeline パイプラインの構築
ではパイプライン本体の作成に進みます。管理コンソールからAWS Data Pipelineのサービスを選択し、[Get Started Now]をクリック。
パイプラインの作成: 名称の設定と利用ソースの選択
パイプラインの『名前』と『説明文』(いずれも内容は任意)入力します。
そして、パイプラインを作成する際の『ソース』を選択。
ここでは、『Build using a template』→『Run AWS CLI command』を選んでください。
ちなみに、templateで選べる内容は以下の様な感じで用意されています。この辺りからのパイプライン作成も今後順次試して行きたいと思います!
パイプラインの作成: パラメータ(AWS CLIコマンド)設定
『Run AWS CLI command』を選ぶと新たに出てくる要素です。以下の様にウォーターマークが表示されていますので、
この様にAWS CLIコマンドを設定します。
パイプラインの作成: スケジュール設定
パイプラインを動かす為の『スケジュール』設定を行います。スケジュールの設定内容には幾つかルールやタイプがありますが、ここでは『毎日定められた時間に実行する』というパターンで行ってみたいと思います。
以下の様な条件設定を行いました。開始(Starting)〜終了(Ending)はこのパイプラインを動かす期間を範囲で指定する形となります。Startingに定めた時間が初回実行の時間となります。ここでは終了の日付を適当(?)ではありますが2020年としてみました。
- Run: "on a schedule"(スケジュールに従う)
- Run every: "1 day(s)"
- Starting: 任意の日付時刻を設定(初回実行のタイミング)
- Ending: 任意の日付時刻を設定(最後の処理が行われるであろうタイミング)
パイプラインの作成: ログ出力設定
AWS Data Pipelineの実行ログ各種を出力する設定を行います。無効(Disabled)とする事も出来ますが、ここは有効(Enabled)が推奨とされていますので、有効にしておきましょう。
出力するバケット名及びフォルダは事前に作成しておいたものを指定する形となっています。予め作成しておいたものを管理コンソール上で指定しておいてください。
パイプラインの作成: IAM設定
AWS Data Pipelineで用いるIAM Roleを指定します。AWS Data Pipelineでは『Role』(事前条件を実行する為に用いられるIAM Role)と『ResourceRole』(Data Pipeline経由で稼働するEC2インスタンスが実行する際に用いるIAM Role)の2つのIAM Roleを使う事になり、ここでDefaultを指定するとそれら2つのIAM Roleのデフォルト指定のIAM Roleを作ってくれます。ここでは初回実行ということでこのDefaultを指定します。
これでひと通りの設定作業が終わりました。[Edit in Architect]を押下。
画面が遷移し、GUIベースの編集画面が表示されました。
IAM: デフォルト作成のIAM Roleに権限付与
AWS Data PipelineでArchitectに進んだら、別ウインドウでIAMの管理画面を開いてください。[Roles]を見てみると、"DataPipeline"で始まる2つのIAM Roleが作成されています。
このうち、『DataPipelineDafaultResourceRole』をクリックして編集画面に進んでください。
今回実行するアクションは『EC2インスタンスの起動』『EC2インスタンスの停止』なので、実行する際の権限がDataPipelineDafaultResourceRoleには付与されておらず、追加する必要があります。[Manage Policy]をクリックし、必要なアクションをIAM Roleに追加します。
以下がその設定例です。(今後用途に応じたIAM Role権限が必要になるようであれば、デフォルトIAM Roleとは別に用途に応じたIAM Roleを作成して利用する事も検討すべきでしょう。)
{ "Statement":[ { "Action":[ "s3:List*", "s3:Put*", "s3:Get*", "s3:DeleteObject", "dynamodb:DescribeTable", "dynamodb:Scan", "dynamodb:Query", "dynamodb:GetItem", "dynamodb:BatchGetItem", "dynamodb:UpdateTable", "rds:DescribeDBInstances", "rds:DescribeDBSecurityGroups", "redshift:DescribeClusters", "redshift:DescribeClusterSecurityGroups", "cloudwatch:PutMetricData", "datapipeline:*", "ec2:StartInstances", "ec2:StopInstances" ], "Effect":"Allow", "Resource":[ "*" ] } ] }
Architectによるパイプライン定義の微調整
Data Pipelineの設定に戻ります。Architectで[Schedule]の欄を改めて確認してみましょう。[Start Date Time(in UTC)]の内容が先程設定された内容と合ってるかどうか改めて確認してみます。(※レイアウトの都合上、若干日付・時刻のテキストボックスが重なりあってしまってますが...) [End Date Time(in UTC)]も同様に内容を確認。
その他の要素も見てみましょう。まずはタスクの中心となる『Activity』について。こちらはShellCommandActivityを使っているようです。Commandの部分を見るとyum updateでAWS CLIの更新を行い、その後の処理を変数で受け取っています。
一方、Activityが参照している『Parameters』の内容はどうなっているかというと、こうなっています。管理コンソール上での入力値(AWS CLI Command)の内容がそのままパラメータとなってShellCommandActivityの変数として利用されているんですね。
『Resource』要素。Data Pipeline経由で稼働するEC2インスタンスのスペックや挙動が設定されています。
『Others』要素。各種要素で追加されるフィールド類が集められているようです。
ひと通り要素を見てみた後で、一旦[Save Pipeline]を押下します。『権限が足りない』旨のワーニングメッセージが併せて表示されますが、EC2インスタンスの操作については先程IAM Roleに対象のアクションを追加しているので実行に差支えはありません。
動作確認
パイプラインのアクティベート
保存が完了したら、[Activate]ボタンを押下。ここでもワーニングメッセージの警告が出て来ますが、実行には差し支えないのでそのまま[Continue]を押下します。
進捗の確認
パイプラインの一覧を見てみると、以下の様に各種要素が一覧表示されています。[Filter=all]を指定すると、Activityの他に、Activityで利用するEC2インスタンスも表示されるようになります。EC2インスタンスは既に作成が始まっていますね。(※このパイプラインは初回処理実行10分〜15分前位に作成しています)
今回検証に使ったパイプラインは毎日AM06:45にEC2インスタンスを起動するスケジュール設定にしています。約5分前。EC2インスタンスが起動し始めました。
EC2インスタンスの一覧も見てみます。対象インスタンスは停止状態、起動するオペレーションを実行するインスタンスが稼働中の状態です。
所定の時間(AM06:45)が過ぎ、暫くして管理コンソールを見てみるとログが生成されていました。
正常時の処理実行ログ(StdOut)の内容です。
Loaded plugins: priorities, security, update-motd, upgrade-helper Setting up Update Process Resolving Dependencies --> Running transaction check ---> Package aws-cli.noarch 0:0.9.3-1.0.amzn1 will be updated ---> Package aws-cli.noarch 0:1.7.3-1.1.amzn1 will be an update --> Processing Dependency: python-botocore = 0.84.0 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Processing Dependency: python-bcdoc = 0.12.2 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Processing Dependency: python-jmespath = 0.5.0 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Processing Dependency: python-rsa >= 3.1.2 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Processing Dependency: python-docutils >= 0.10 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Processing Dependency: python-colorama >= 0.2.5 for package: aws-cli-1.7.3-1.1.amzn1.noarch --> Running transaction check ---> Package python-bcdoc.noarch 0:0.12.2-1.0.amzn1 will be installed ---> Package python-botocore.noarch 0:0.9.2-1.0.amzn1 will be updated ---> Package python-botocore.noarch 0:0.84.0-1.1.amzn1 will be an update --> Processing Dependency: python-simplejson >= 3.3.0 for package: python-botocore-0.84.0-1.1.amzn1.noarch ---> Package python-colorama.noarch 0:0.2.4-1.1.amzn1 will be updated ---> Package python-colorama.noarch 0:0.2.5-1.4.amzn1 will be an update ---> Package python-docutils.noarch 0:0.11-1.11.amzn1 will be installed ---> Package python-jmespath.noarch 0:0.0.2-1.0.amzn1 will be updated ---> Package python-jmespath.noarch 0:0.5.0-1.1.amzn1 will be an update ---> Package python-rsa.noarch 0:3.1.2-4.3.amzn1 will be installed --> Running transaction check ---> Package python-simplejson.x86_64 0:3.5.3-1.7.amzn1 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Updating: aws-cli noarch 1.7.3-1.1.amzn1 amzn-updates 586 k Installing for dependencies: python-bcdoc noarch 0.12.2-1.0.amzn1 amzn-main 29 k python-docutils noarch 0.11-1.11.amzn1 amzn-main 1.9 M python-rsa noarch 3.1.2-4.3.amzn1 amzn-main 72 k python-simplejson x86_64 3.5.3-1.7.amzn1 amzn-main 201 k Updating for dependencies: python-botocore noarch 0.84.0-1.1.amzn1 amzn-updates 1.7 M python-colorama noarch 0.2.5-1.4.amzn1 amzn-main 23 k python-jmespath noarch 0.5.0-1.1.amzn1 amzn-updates 37 k Transaction Summary ================================================================================ Install 4 Package(s) Upgrade 4 Package(s) Total download size: 4.5 M Downloading Packages: -------------------------------------------------------------------------------- Total 4.1 MB/s | 4.5 MB 00:01 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Updating : python-jmespath-0.5.0-1.1.amzn1.noarch 1/12 Installing : python-docutils-0.11-1.11.amzn1.noarch 2/12 Installing : python-bcdoc-0.12.2-1.0.amzn1.noarch 3/12 Updating : python-colorama-0.2.5-1.4.amzn1.noarch 4/12 Installing : python-simplejson-3.5.3-1.7.amzn1.x86_64 5/12 Updating : python-botocore-0.84.0-1.1.amzn1.noarch 6/12 Installing : python-rsa-3.1.2-4.3.amzn1.noarch 7/12 Updating : aws-cli-1.7.3-1.1.amzn1.noarch 8/12 Cleanup : aws-cli-0.9.3-1.0.amzn1.noarch 9/12 Cleanup : python-botocore-0.9.2-1.0.amzn1.noarch 10/12 Cleanup : python-jmespath-0.0.2-1.0.amzn1.noarch 11/12 Cleanup : python-colorama-0.2.4-1.1.amzn1.noarch 12/12 Verifying : python-bcdoc-0.12.2-1.0.amzn1.noarch 1/12 Verifying : python-docutils-0.11-1.11.amzn1.noarch 2/12 Verifying : aws-cli-1.7.3-1.1.amzn1.noarch 3/12 Verifying : python-botocore-0.84.0-1.1.amzn1.noarch 4/12 Verifying : python-rsa-3.1.2-4.3.amzn1.noarch 5/12 Verifying : python-jmespath-0.5.0-1.1.amzn1.noarch 6/12 Verifying : python-simplejson-3.5.3-1.7.amzn1.x86_64 7/12 Verifying : python-colorama-0.2.5-1.4.amzn1.noarch 8/12 Verifying : python-colorama-0.2.4-1.1.amzn1.noarch 9/12 Verifying : aws-cli-0.9.3-1.0.amzn1.noarch 10/12 Verifying : python-botocore-0.9.2-1.0.amzn1.noarch 11/12 Verifying : python-jmespath-0.0.2-1.0.amzn1.noarch 12/12 Dependency Installed: python-bcdoc.noarch 0:0.12.2-1.0.amzn1 python-docutils.noarch 0:0.11-1.11.amzn1 python-rsa.noarch 0:3.1.2-4.3.amzn1 python-simplejson.x86_64 0:3.5.3-1.7.amzn1 Updated: aws-cli.noarch 0:1.7.3-1.1.amzn1 Dependency Updated: python-botocore.noarch 0:0.84.0-1.1.amzn1 python-colorama.noarch 0:0.2.5-1.4.amzn1 python-jmespath.noarch 0:0.5.0-1.1.amzn1 Complete! { "StartingInstances": [ { "InstanceId": "i-d40af9f9", "CurrentState": { "Code": 16, "Name": "running" }, "PreviousState": { "Code": 16, "Name": "running" } } ] }
改めてEC2インスタンスの状況を見てみます。起動対象のEC2インスタンスが稼働を始め、
処理を終えたEC2リソースインスタンスはシャットダウン処理に入りました。
タスクが終わった後のパイプラインのステータス状況です。
実行ログも、該当バケット内に生成されていました。
まとめ
以上、AWS Data Pipelineで日々の定型作業(AWS CLI)を自動化するエントリのご紹介でした。
AWS Data Pipelineでの要素の構成、実行制御自体ちょっとした癖がありますが、この辺りも幾つか試行錯誤を重ねて行く事でコツみたいなものも分かってきたような気がします。
また、今回試したケース(AWS CLIの実行)は(恐らく)一番シンプルなものになると思われます。日々の定型作業の中にはより複雑な・広範なケースも多々あるかと思いますので、今後その他の定型作業(のAWS Data Pipeline置き換え)にも適用出来るような構成・ケースをご紹介して行ければと思います。こちらからは以上です。