LoginSignup
4
3

TerraformでAWS Lambdaをデプロイする方法

Last updated at Posted at 2023-08-25

やりたいこと

・TerraformでAWS Lambdaをデプロイしたい
・ローカルでlambdaソースを編集したらAWSへ連動できるか検証したい

前提

・AWSアカウント作成済み
・AWS IAMユーザーを作成し、access_keyとsecret_keyを発行済み
・Terraformインストール済み
・AWS CLIインストール済み
・VSCODEインストール済み
 (お好みのエディターで大丈夫)
・Pythonインストール済み
 (今回はpython3.9でlambadaを作ってみたいですが、極簡単なソースコードなのでバージョンどうてもいいかと思う)

環境

$ terraform -v 
Terraform v1.5.5
on windows_amd64
+ provider registry.terraform.io/hashicorp/aws v5.13.1

$ python -V
Python 3.9.13

構築リソース

・AWS Lambda function
・AWS IAM role
・AWS IAM policy

ディレクトリ構成

必要最小限のソース構成ですが

root
  ┣━ lambda
  ┃  ┗━ test
  ┃     ┗━ src
  ┃        ┣━ test_terraform.py
  ┃        ┗━ test_terraform.zip          
  ┣━ main.tf
  ┣━ variables.tf
  ┗━ lambda.tf

※補足
・lambdaフォルダに複数lambda functionのソースコードを入れる予定でtestフォルダで階層を掘ってますが、適宜階層を変えてもらって大丈夫
・test_terraform.zipはterraform実行で自動で作られたやつで、自分で用意する必要がない(後述説明)

ソースの中身

main.tf

・main.tfには基本、全体共通で重要な設定、例えば「AWS プロバイダの設定」を書く
・lambda関数実行時、cloudWatchへログを書き込むのに権限が必要、今回は三つの権限を付与してあげたいと思う
・今回は便宜上そのIAM設定を一緒にmain.tfに入れた。別途iam.tfで分けて作っても大丈夫

main.tf
# AWS プロバイダの設定
provider "aws" {
  access_key = var.access_key
  secret_key = var.secret_key
  region     = var.region
}

# lambda用Roleの設定
resource "aws_iam_role" "lambda_iam_role" {
  name = "terraform_lambda_iam_role"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
POLICY
}

# lambda用Policyの作成
resource "aws_iam_role_policy" "lambda_access_policy" {
  name   = "terraform_lambda_access_policy"
  role   = aws_iam_role.lambda_iam_role.id
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream",
        "logs:CreateLogGroup",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}
POLICY
}

variables.tf

・variables.tfに全ソース共通の変数を書く
・リージョンは東京にしたが、適宜変更して大丈夫
・access_keyとsecret_keyは事前に発行したやつを使用

variables.tf
variable "region" {
  default = "ap-northeast-1"
}

variable "access_key" {
  default = "自分のaccess_key"
}

variable "secret_key" {
  default = "自分のsecret_key"
}

lambda.tf

・terraformのdataで、ローカルにあるpythonのソースのパスを教えてあげて、後でterraform plan実行時にzip化してくれて便利!
・terraform apply時は、source_code_hash(さっき作ったソースのzipファイル)をlambdaにアップしてくれる

lambda.tf
# ローカルにあるlambdaのソースコード
data "archive_file" "test_terraform" {
  type        = "zip"
  source_dir  = "lambda/test/src"
  output_path = "lambda/test/src/test_terraform.zip"
}

# AWSへ作るlambda function
resource "aws_lambda_function" "test_terraform" {
  function_name    = "test_terraform"
  filename         = data.archive_file.test_terraform.output_path
  source_code_hash = data.archive_file.test_terraform.output_base64sha256
  runtime          = "python3.9"
  role             = aws_iam_role.lambda_iam_role.arn
  handler          = "test_terraform.handler"
}

test_terraform.py

・どうでもいいテストの内容ですwww

test_terraform.py
def handler(event, context):
    print('test')

    return()

Terraformでlambda functionを新規作成

念のため初期化してあげよう

terraform init

これが出たら成功かな

実行結果
Terraform has been successfully initialized!

次にterraformの実行計画を確認しよう

terraform plan

新規ファイル、もしくは増分か差分がある場合、こういうふうに結果が出てくる

実行結果
Plan: 4 to add, 0 to change, 0 to destroy.

terraform planを実行後、zip化したpythonのファイルが出てくるはず

image.png
そして、AWSへデプロイしよう!

terraform apply

ちゃんと成功したそうです!
今回は新規作成なので、「4 added」と表示してますが、今後修正分を反映するときは、changed(増分差分の反映)かdestroyed(削除)となるはず。

実行結果
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

AWS側を確認すると、AWS functionが立派にできてます!ちゃんとpython3.9になってますね!
image.png
AWS functionのソースを見てみると、zipファイルがちゃんとアップされ、ソースの中身は無事書き込まれた!
image.png
そして、lambda functionの持ってるIAM権限を確認すると、さっき作ってあげた三つの権限はちゃんと付与されてます!
image.png
ついてに、IAMも確認しよう!
lambdaへ付与したいロールは作られて、
image.png
cloudWatchへログを書き込むための三つの権限を持ってるpolicyも作られた!
image.png
最後、AWSで一回lambda functionを実行したうえ、cloudWatchを確認しよう!
image.png
lambda function専用のロググループが作られて、さっき実行した記録も残ってますね!
image.png

ローカルでlambdaのソースコードを編集

先ほどterraformで作られたlambada functionはちゃんとterraformの管理配下になってるか知りたいので、少しtest_terraform.pyを修正してみよう

test_terraform.py
def handler(event, context):
    print('test again')

    return()

そして、もう一度コマンドを実行

terraform plan

一つ変更があるよって、教えてくれた

実行結果
Plan: 0 to add, 1 to change, 0 to destroy.

この時点でzipも作り直してくれたようです(日付が更新された)
image.png

では変更した分をAWSへデプロイしようと、

terraform apply

一個変更分をデプロイしたって、言ってますね

実行結果
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

最後、AWS側を確認すると、ソースコードをちゃんと最新化してくれた
image.png

終わりに

お疲れ様です!今回のやりたいことが無事終わった!
・TerraformでAWS Lambdaをデプロイしたい 
 ⇒デプロイできた
・ローカルでlambdaソースを編集したらAWSへ連動できるか検証したい 
 ⇒連動できる、terraform planで管理されてる

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3