S3にファイルが作成されたときにEC2にコピーするLambda関数を作成したのでブログに残します。
作成したLambda関数
以下のコードを作成しました。
from datetime import datetime
import boto3
import os
ssm = boto3.client('ssm')
instance_id = os.environ['instance_id']
now = datetime.now()
file_name = 'file_name' + now.strftime('%Y%m%d%H%M%S')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
response = ssm.send_command(
InstanceIds=[instance_id],
DocumentName='AWS-RunShellScript',
Parameters={
'commands': [
f'aws s3 cp s3://{bucket}/{key} /home/ec2-user/{file_name}'
],
'executionTimeout': ['3600'],
}
)
こちらはS3にファイルが作成されるとAWS Systems Manager Run CommandでAWS-RunShellScriptドキュメントを実行します。
AWS-RunShellScriptはSystems Managerのマネージドノードに対してコマンドを実行することができるものになります。
今回は「aws s3 cp」を実行してS3で作成されたファイルをec2-userのホームディレクトリにfile_nameyyyymmddhhmmssというファイル名で作成します。
send_command
デプロイ
Lambdaの作成はAWS SAMを使用しました。
コマンドを実行する環境はCloudShellを使用しています。
今回Pythonの3.9を使用しているので以下のコマンドを実行してPython 3.9が使用できるようにします。
sudo yum install gcc openssl-devel bzip2-devel libffi-devel -y
wget https://www.python.org/ftp/python/3.9.17/Python-3.9.17.tgz
tar xzf Python-3.9.17.tgz
cd Python-3.9.17
./configure --enable-optimizations --prefix=$HOME/.local
sudo make altinstall
cd ..
sudo rm -rf Python-3.9.17 Python-3.9.17.tgz
作成したtemplate.yamlは以下になります。
今回は既にSystems ManagerにマネージドノードのEC2が追加されている前提で進めます。
マネージドノードについてはこちらのドキュメントをご確認ください。
Lambda関数以外にもS3とIAMロールも一緒に作成をしています。
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: SSM RunCommand
Parameters:
instanceid:
Type: String
Resources:
FunctionIamPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "logs:CreateLogGroup"
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*"
- Effect: Allow
Action:
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/function-ssm-runcommand-${AWS::Region}:*"
- Effect: Allow
Action:
- "ssm:SendCommand"
Resource: "*"
ManagedPolicyName: !Sub "policy-lambda-ssm-runcommand-${AWS::Region}"
FunctionIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action: "sts:AssumeRole"
Effect: Allow
Principal:
Service: lambda.amazonaws.com
ManagedPolicyArns:
- !Ref FunctionIamPolicy
RoleName: !Sub "role-lambda-ssm-runcommand-${AWS::Region}"
Tags:
- Key: Name
Value: !Sub "role-lambda-ssm-runcommand-${AWS::Region}"
S3:
Type: AWS::S3::Bucket
DependsOn: Function
Properties:
BucketName: !Sub s3-${AWS::AccountId}
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
NotificationConfiguration:
LambdaConfigurations:
- Event: "s3:ObjectCreated:*"
Function: !GetAtt Function.Arn
Function:
Type: AWS::Serverless::Function
Properties:
CodeUri: function/
Environment:
Variables:
instance_id: !Ref instanceid
Events:
S3:
Properties:
Bucket: !Ref S3
Events: s3:ObjectCreated:*
Type: S3
FunctionName: !Sub function-ssm-runcommand-${AWS::Region}
Handler: lambda_function.lambda_handler
Role: !GetAtt FunctionIamRole.Arn
Runtime: python3.9
Timeout: 900
Lambda関数のコードとtemplate.yamlは私のGitHubリポジトリに保管しています。
今回はそこからクローンしてデプロイする手順を記載します。
以下のコマンドを実行します。
git clone https://github.com/Kobayashi-Riku0226/lambda_repository.git
cd lambda_repository/ssm_runcommand
sam build
sam deploy --stack-name スタック名 --s3-bucket CloudFormationテンプレートを格納するS3バケット --capabilities CAPABILITY_NAMED_IAM --parameter-overrides instanceid=ファイルをコピーするEC2インスタンス ID
動作確認
動作確認は上記のデプロイで作成されたS3バケットにファイルをputします。
以下のコマンドをCloudShellで実行してください。
echo "test file" > test.txt
aws s3 cp ./test.txt s3://S3バケット名
実行後、ファイルをコピーするEC2インスタンスにSSHやSession Managerで接続してec2-userのホームディレクトリを見るとファイルが作成されていることが確認できます。
ls -la /home/ec2-user/
total 20
drwx------. 3 ec2-user ec2-user 136 Jun 29 08:02 .
drwxr-xr-x. 4 root root 38 Jun 29 06:54 ..
-rw-r--r--. 1 ec2-user ec2-user 18 Jan 28 22:29 .bash_logout
-rw-r--r--. 1 ec2-user ec2-user 141 Jan 28 22:29 .bash_profile
-rw-r--r--. 1 ec2-user ec2-user 492 Jan 28 22:29 .bashrc
drwx------. 2 ec2-user ec2-user 29 Jun 28 14:22 .ssh
-rw-r--r--. 1 root root 10 Jun 29 08:02 file_name20230629080257
さいごに
今回はS3にファイルが作成されたときにEC2にファイルをコピーするLambda関数を作成してみました。
設定自体はシンプルなのでS3のイベント起因でコマンドを実行したいみたいな時の参考になればと思います。