この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも!大阪オフィスの西村祐二です。
S3にアップロードされたファイルをEC2内に自動的にダウンロードしたいと思うことはよくあると思います。 自動化する方法はいろいろあると思いますが、 今回はLambdaとSSM、AWS CLIを使って自動化してみたいと思います。
さっそくやってみましょう。
構成図
今回、想定する構成が下記の図になります。
S3にファイルがアップロードされたら、LambdaからSSMを実行し、
EC2(Windows)にてAWSCLIのS3 Sync
コマンドを実行します。
この構成の利点
私が思うこの構成の利点としては、 ・EC2側はAWS CLI設定とSSM Agentのインストールだけで済み、今後の運用不可が軽減されそう ・Lambdaの実装がSSMを実行する部分のみになる
はじめはEC2にFTPサーバをたてて、LambdaでS3からファイルを取得し、EC2にコピーしようと思いましたが、 FTPサーバを立ててしまうと、FTPサーバの設定や、ポート、FTPログなど 新たに管理しなければいけない項目が増えてしまいそうだと思い、、 また、コピーする際にLambdaの制限を考慮したり、EC2へのログイン処理など すこし大袈裟な処理になりそうでしたので、今回はシンプルにLambdaはSSMを実行するだけとし S3にアップロードされたファイルはEC2から取得する構成としてみました。
環境
■Windows: Windows Server 2016
■セキュリティグループ:
インバウンドは作業用にマイIPのみ許可しています。
■Lambda:
・ランタイム:python3.6
作業概要
■EC2(Windows):
・AWS CLI環境を構築する ・SSM Agentをインストールし、設定する
■Lambda:
・S3へのアップロードをトリガーとするLambdaからSSMを実行する関数を作成する
EC2(Windows)の作業:AWS CLI環境を構築する
同期用のIAMユーザを作成する
今回、EC2からS3のファイルをダウンロードするため、 まず、S3への権限を付与したIAMユーザを作っておきましょう。 既存のユーザがあるなら、そちらでも大丈夫です。
▼マネージメントコンソールからIAMのサービス画面に移動し、「ユーザを追加」をクリックします
▼ユーザ名を「test-s3-sync」として、「プログラムによるアクセス」にチェックします
▼アクセス権限はS3へのアクセスを許可するポリシーをアタッチしておきます
▼CSVをダウンロードしておき、アクセスキーIDとシークレットアクセスキーをメモしておきます
EC2(Windows)にてAWS CLIを設定する
▼下記ドキュメントを参考にAWS CLIをインストールします。
Microsoft Windows で AWS Command Line Interface をインストールする
インストールが完了したらpowershellなどで下記コマンドを実行し、AWS CLIの情報が出力されるか確認します。
> aws --version
aws-cli/1.11.189 Python/2.7.9 Windows/2012Server botocore/1.7.47
▼プロファイルの設定をします。
powershellから
aws configure --profile s3-sync-user
と入力して設定していきます。
今回はプロファイル名「s3-sync-user」として設定しています。
AWS Access Key ID
と
AWS Secret Access Key
には、ダウンロードしたCSVに記載されていた値を入力します。
▼動作確認を行います。
設定がうまくいっていれば、aws s3 ls s3://<バケット名> --profile s3-sync-user
で
S3のバケットの中身が確認できます。
EC2(Windows)の作業:SSM Agentをインストールし、設定する
下記ドキュメントを参考にSSM Agentをインストールします。
Windows インスタンスで SSM エージェント をインストールし設定する
EC2用のIAMロールを設定する
▼EC2とSSMがアクセスするために、EC2にIAMロールを設定します。
▼作成した「test-ssm」を選択し、EC2にIAMロールを設定します。
▼SSMのAgentやIAMの設定が完了したら、きちんと認識されているか確認します。
▼認識されていたら、画像のようにインスタンスIDがみえます。
Lambda関数を作成します
下記がサンプルプログラムになります。 対象のインスタンスIDと、EC2で実行してほしいコマンドを設定します。
今回はAWS-RunPowerShellScript
を使って
EC2内のデスクトップにある、「s3-sync」というフォルダに
S3のバケット内のファイルをダウンロードします。
EC2内で実行されるコマンド
aws s3 sync s3:// C:\Users\Administrator\Desktop\s3-sync\
また、対象のバケットをトリガーとする設定と、IAMにはEC2とSSMの権限を付与しておいてください。
lambda_function.py
"""This is a test program."""
import logging
import boto3
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
EC2 = boto3.client('ec2')
SSM = boto3.client('ssm')
INSTANCE_ID = 'i-0XXXXXXXXXXXXX'
def lambda_handler(event, context):
"""
Run 'S3 sync command'in Windows from Lambda
"""
try:
# Get EC2 State
ec2_resp = EC2.describe_instances(InstanceIds=[INSTANCE_ID])
ec2_state = ec2_resp['Reservations'][0]['Instances'][0]['State']['Name']
if not ec2_state == "running":
LOGGER.info('No EC2 is running')
return "END"
# RunPowerShellScript
command = r'aws s3 sync s3://<your target bucket> C:\Users\Administrator\Desktop\s3-sync\ '
SSM.send_command(
InstanceIds=[INSTANCE_ID],
DocumentName="AWS-RunPowerShellScript",
Parameters={
"commands":[command],
"executionTimeout":["3600"]
},
)
except Exception as error:
LOGGER.error(error)
raise error
動作確認
トリガーとなるバケットにファイルをアップロードし、EC2へ同期されるか確認してみます。
想定通り、バケットへファイルを追加すると、右側のEC2のフォルダでもファイルがふえていることがわかります。
さいごに
いかがだったでしょうか。
Lambdaを使ってS3にアップロードされたファイルを自動的にEC2(Windows)内にダウンロード(同期)してみました。 EC2にてAWS CLIの設定と、SSM Agentのインストールを行えば、簡単に実現することができます。 要件次第ではありますが、FTPサーバを利用するより運用コストも軽微で済むのではないでしょうか。
誰かの参考になれば幸いです。