Pythonで書いたシンプルなスクリプトをTerraformを用いてAWS Lambdaにデプ ロイする方法を示す。
Terraformの設定
AWS Lambdaで用いるPythonスクリプトのアーカイブ
ここが一番気になるところだろう。シンプルなPythonスクリプトの場合、わざ
わざリポジトリを分割したくないしパッケージングもしたくない。できれば
Terraformの構成と同様にPythonスクリプトも管理したい。Terraformはこの要
求にももちろん答えることができる。Terraformの archive_file pluginを
用いてTerraformの適応と同時にZIPファイルとしてアーカイブを作成し、それ
を用いてAWS Lambdaへの展開を行う。
以下では example_lambda_functions 配下に "example.py" というファイル
を予め配置している。このファイルがAWS Lambdaに展開するPythonスクリプト
になる。 source_file でアーカイブに含めるファイルを指定している。
output_path で出力するアーカイブのパスを指定している。ここには
Terraformの適応毎にアーカイブが出力されるため、Gitに登録しないように
.gitignore に指定する。
data "archive_file" "example_lambda_functions_zip" {
type = "zip"
source_file = "${path.module}/example_lambda_functions/example.py"
output_path = "${path.module}/files/example_lambda_functions.zip"
}
AWS Lambdaで用いるIAM Roleの定義
AWS Lambdaを定義する際にIAM Roleが必要になるので作成しておく。
resource "aws_iam_role" "iam_for_example_function" {
name = "iam_for_example_function"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
AWS Lambdaの定義
上記のリソースを用いてAWS Lambdaを定義する。
resource "aws_lambda_function" "example_function" {
filename = data.archive_file.example_lambda_functions_zip.output_path
function_name = "example"
role = aws_iam_role.iam_for_example_function.arn
handler = "example.lambda_handler"
source_code_hash = data.archive_file.example_lambda_functions_zip.output_base64sha256
runtime = "python3.8"
memory_size = 128
timeout = 30
}
ローカルでのデプロイ
Terraformが呼び出すAWSのAPIは設定により変更できるため、AWSのAPIをエミュ レートするダミーサーバーに対して動作確認を行える。以下ではDockerを用い てlocalstackを起動し、それをダミーサーバーとして動作を確認する方法を示 す。
localstackを起動する
localstackとはAWSのAPIをエミュレートするAPIサーバーである。ローカル環 境での検証のために用いる。localstackの起動のためにDockerや docker-composeを用いることが必須というわけではないが、ここではそれを採 用する。
docker-compose.ymlを作成し、以下を記述する。
version: "3.8"
services:
localstack:
image: localstack/localstack:0.12.2
ports:
- "4566:4566"
- "4569:4569"
environment:
- "DEFAULT_REGION=ap-northeast-1"
ファイルを保存したらコンテナを起動する。
$ docker-compose up
ローカルで起動しているlocalstackに対してTerraformを行う際にはこのコン
テナが起動していることが必要となる。起動したままの状態でコマンドを復帰
させたければ docker-compose up -d とするのが良いだろう。このコンテナ
は4566番のTCPポートでリクエストを待ち受けているため、通常
http://localhost:4566 に対してリクエストを送信できる。
Terraformが呼び出すAWSのAPIエンドポイントをローカルに変更する
Terraformが呼び出したAWSのAPIがローカルに起動したlocalstackに送信されるように設定を変更する。
provider "aws" {
region = "ap-northeast-1"
access_key = "mock_access_key"
secret_key = "mock_secret_key"
s3_force_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
accessanalyzer = "http://localhost:4566"
acm = "http://localhost:4566"
acmpca = "http://localhost:4566"
amplify = "http://localhost:4566"
apigateway = "http://localhost:4566"
applicationautoscaling = "http://localhost:4566"
applicationinsights = "http://localhost:4566"
appmesh = "http://localhost:4566"
appstream = "http://localhost:4566"
appsync = "http://localhost:4566"
athena = "http://localhost:4566"
autoscaling = "http://localhost:4566"
autoscalingplans = "http://localhost:4566"
backup = "http://localhost:4566"
batch = "http://localhost:4566"
budgets = "http://localhost:4566"
cloud9 = "http://localhost:4566"
cloudformation = "http://localhost:4566"
cloudfront = "http://localhost:4566"
cloudhsm = "http://localhost:4566"
cloudsearch = "http://localhost:4566"
cloudtrail = "http://localhost:4566"
cloudwatch = "http://localhost:4566"
cloudwatchevents = "http://localhost:4566"
cloudwatchlogs = "http://localhost:4566"
codeartifact = "http://localhost:4566"
codebuild = "http://localhost:4566"
codecommit = "http://localhost:4566"
codedeploy = "http://localhost:4566"
codepipeline = "http://localhost:4566"
codestarconnections = "http://localhost:4566"
# codestarnotifications = "http://localhost:4566"
cognitoidentity = "http://localhost:4566"
cognitoidp = "http://localhost:4566"
configservice = "http://localhost:4566"
connect = "http://localhost:4566"
cur = "http://localhost:4566"
dataexchange = "http://localhost:4566"
datapipeline = "http://localhost:4566"
datasync = "http://localhost:4566"
dax = "http://localhost:4566"
devicefarm = "http://localhost:4566"
directconnect = "http://localhost:4566"
dlm = "http://localhost:4566"
dms = "http://localhost:4566"
docdb = "http://localhost:4566"
ds = "http://localhost:4566"
dynamodb = "http://localhost:4566"
ec2 = "http://localhost:4566"
ecr = "http://localhost:4566"
ecrpublic = "http://localhost:4566"
ecs = "http://localhost:4566"
efs = "http://localhost:4566"
eks = "http://localhost:4566"
elasticache = "http://localhost:4566"
elasticbeanstalk = "http://localhost:4566"
elastictranscoder = "http://localhost:4566"
elb = "http://localhost:4566"
emr = "http://localhost:4566"
emrcontainers = "http://localhost:4566"
es = "http://localhost:4566"
firehose = "http://localhost:4566"
fms = "http://localhost:4566"
forecast = "http://localhost:4566"
fsx = "http://localhost:4566"
gamelift = "http://localhost:4566"
glacier = "http://localhost:4566"
globalaccelerator = "http://localhost:4566"
glue = "http://localhost:4566"
guardduty = "http://localhost:4566"
greengrass = "http://localhost:4566"
iam = "http://localhost:4566"
identitystore = "http://localhost:4566"
imagebuilder = "http://localhost:4566"
inspector = "http://localhost:4566"
iot = "http://localhost:4566"
iotanalytics = "http://localhost:4566"
iotevents = "http://localhost:4566"
kafka = "http://localhost:4566"
kinesis = "http://localhost:4566"
kinesisanalytics = "http://localhost:4566"
kinesisanalyticsv2 = "http://localhost:4566"
kinesisvideo = "http://localhost:4566"
kms = "http://localhost:4566"
lakeformation = "http://localhost:4566"
lambda = "http://localhost:4566"
lexmodels = "http://localhost:4566"
licensemanager = "http://localhost:4566"
lightsail = "http://localhost:4566"
macie = "http://localhost:4566"
macie2 = "http://localhost:4566"
managedblockchain = "http://localhost:4566"
marketplacecatalog = "http://localhost:4566"
mediaconnect = "http://localhost:4566"
mediaconvert = "http://localhost:4566"
medialive = "http://localhost:4566"
mediapackage = "http://localhost:4566"
mediastore = "http://localhost:4566"
mediastoredata = "http://localhost:4566"
mq = "http://localhost:4566"
mwaa = "http://localhost:4566"
neptune = "http://localhost:4566"
networkfirewall = "http://localhost:4566"
networkmanager = "http://localhost:4566"
opsworks = "http://localhost:4566"
organizations = "http://localhost:4566"
outposts = "http://localhost:4566"
personalize = "http://localhost:4566"
pinpoint = "http://localhost:4566"
pricing = "http://localhost:4566"
# prometheusservice = "http://localhost:4566"
qldb = "http://localhost:4566"
quicksight = "http://localhost:4566"
ram = "http://localhost:4566"
rds = "http://localhost:4566"
redshift = "http://localhost:4566"
resourcegroups = "http://localhost:4566"
resourcegroupstaggingapi = "http://localhost:4566"
route53 = "http://localhost:4566"
route53domains = "http://localhost:4566"
route53resolver = "http://localhost:4566"
s3 = "http://localhost:4566"
s3control = "http://localhost:4566"
s3outposts = "http://localhost:4566"
sagemaker = "http://localhost:4566"
sdb = "http://localhost:4566"
secretsmanager = "http://localhost:4566"
securityhub = "http://localhost:4566"
serverlessrepo = "http://localhost:4566"
servicecatalog = "http://localhost:4566"
servicediscovery = "http://localhost:4566"
servicequotas = "http://localhost:4566"
ses = "http://localhost:4566"
shield = "http://localhost:4566"
signer = "http://localhost:4566"
sns = "http://localhost:4566"
sqs = "http://localhost:4566"
ssm = "http://localhost:4566"
ssoadmin = "http://localhost:4566"
stepfunctions = "http://localhost:4566"
storagegateway = "http://localhost:4566"
sts = "http://localhost:4566"
swf = "http://localhost:4566"
synthetics = "http://localhost:4566"
timestreamwrite = "http://localhost:4566"
transfer = "http://localhost:4566"
waf = "http://localhost:4566"
wafregional = "http://localhost:4566"
wafv2 = "http://localhost:4566"
worklink = "http://localhost:4566"
workmail = "http://localhost:4566"
workspaces = "http://localhost:4566"
xray = "http://localhost:4566"
}
}
長くなったが必要な部分だけを設定すればよい。
Terraformの実行
実行方法は通常の方法と変わらない。
適応した際の変更内容を確認する場合には terraform plan を実行する。
$ terraform plan
実際に適応する場合には terraform apply を実行する。
$ terraform apply
AWS Lambdaのコンテナサポートを使う
AWS LambdaはDockerコンテナをサポートしている。AWS Lambdaのコンテナサポー トを使う ではAWS LambdaはDockerコンテナをサポートをどのように実装する かについて記述した。