Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Terraform と Serverless Framework を相互連携する

Terraform と Serverless Framework を相互連携する

HashiTalks: Japan 2022 で発表した資料になります。

dodonki1223

August 25, 2022
Tweet

Other Decks in Technology

Transcript

  1. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 6
  2. 1. 題材 AWS 初心者向けハンズオン の「 サーバーレスアーキテクチャで翻訳 Web API を構築する 」は動画を10個見ながら言われたとおりにしてい

    くだけで2時間もあれば簡単に実装することが出来ます。 私もこちらのハンズオンの終了後に Terraform と Serverless Framework を使って実装し直しました。 実装していった過程も含めて発表していきます! 9
  3. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 10
  4. 2. Terraform と Serverless Framework で管理するもの Terraform では IAM ロール

    と AWS Systems Manager Parameter Store の2つを管理します。 後に説明しますが AWS Systems Manager Parameter Store は Serverless Framework と連携するために必要になります。 12
  5. 2. Terraform と Serverless Framework で管理するもの Serverless Framework では Amazon

    API Gateway と AWS Lambda と Amazon DynamoDB と CloudWatch Logs の4つを管理します。 13
  6. 2. Terraform と Serverless Framework で管理するもの Serverless Framework で管理しているリソースが多くない? Serverless

    Framework で多くのリソースを管理しているのは ローカ ルの開発環境が整っている ためです。 ローカルの開発環境で使用する必要があるのものは Serverless Framework で管理 し それ以外は Terraform で管理する ようにしてい ます。 今日はローカルの開発環境については詳しく説明しません。 14
  7. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 16
  8. 3. Serverless Framework を使ってコード化 Serverless Framework コマンドをインストール $ npm install

    -g serverless フォルダを作成し移動 $ mkdir serverless $ cd serverless ハンズオンと同じ Python のプロジェクトを指定して作成する $ serverless create --template aws-python3 --name translate-function ハンズオンと同じファイル名に変更する $ mv handler.py translate_function.py 17
  9. 3. Serverless Framework を使ってコード化 serverless という AWS profile を予め設定 しておきます。既に作成されている

    serverless.yml に以下の内容のように改修します。 service: translate-function frameworkVersion: '3' provider: name: aws runtime: python3.8 region: ap-northeast-1 profile: serverless functions: translate: name: translate-function handler: translate_function.lambda_handler 18
  10. 3. Serverless Framework を使ってコード化 translate_function.py も以下の内容のように改修します。 import json def lambda_handler(event,

    context): body = { "message": "Go Serverless v1.0! Your function executed successfully!", "input": event } response = { "statusCode": 200, "body": json.dumps(body) } return response 19
  11. 3. Serverless Framework を使ってコード化 serverless deploy コマンドを実行すると AWS Lambda 以外にも

    CloudWatch Logs, IAM Role が作成 されます。 IAM ロールは後に Terraform で作成したものに移行する予定です。 Amazon API Gateway, Amazon DynamoDB も作っていき、ハンズオンと同じ状態 にしていきます。 20
  12. 3. Serverless Framework を使ってコード化 serverless.yml の provider に endpointType と

    handler の下に events を追加し Amazon API Gateway と AWS Lambda が繋ぎ込みされるようにします。 input_text でクエリパラメータを取得できるようになります。 service: translate-function frameworkVersion: '3' provider: name: aws runtime: python3.8 region: ap-northeast-1 profile: serverless endpointType: regional functions: translate: name: translate-function handler: translate_function.lambda_handler events: - http: method: get path: /translate request: parameters: querystrings: input_text: false 21
  13. 3. Serverless Framework を使ってコード化 Amazon Translate, Amazon DynamoDB にアクセスできるように AWS

    Lambda で使用されている IAM ロールに一時的に権限を付与します。 22
  14. 3. Serverless Framework を使ってコード化 serverless.yml に resources を追加し DynamoDB の

    table を作成します。 service: translate-function frameworkVersion: '3' provider: name: aws runtime: python3.8 region: ap-northeast-1 profile: serverless endpointType: regional functions: translate: name: translate-function handler: translate_function.lambda_handler events: - http: method: get path: /translate request: parameters: querystrings: input_text: false resources: Resources: usersTable: Type: AWS::DynamoDB::Table Properties: TableName: translate-history AttributeDefinitions: - AttributeName: timestamp AttributeType: S KeySchema: - AttributeName: timestamp KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 24
  15. 3. Serverless Framework を使ってコード化 translate_function.py を改修し 日本語を英語に翻訳する機能 と 翻訳結果を DynamoDB

    に保存する処理 を実装します。 import os import boto3 import json import datetime translate = boto3.client('translate') dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history') def lambda_handler(event, context): input_text = event['queryStringParameters']['input_text'] response = translate.translate_text( Text=input_text, SourceLanguageCode='ja', TargetLanguageCode='en', ) output_text = response.get('TranslatedText') dynamodb_translate_history_tbl.put_item( Item = { 'timestamp': datetime.datetime.now().strftime("%Y%m%d%H%M%S"), 'input_text': input_text, 'output_text': output_text } ) return { 'statusCode': 200, 'body': json.dumps({ 'output_text': output_text }), 'isBase64Encoded': False, 'headers': {} } 25
  16. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 27
  17. 4. Terrafomer を使ってコード化 Terraformer を使って Serverless Framework で仮で作成した IAM ロールを取り込

    みコード化 します。 Terraformer を使用することで Terraform の管理化でないリソースをコード化 して くれるのでとても便利です! Terraformer は以下のコマンドで簡単にインストール可能です。 $ brew install terraformer 28
  18. 4. Terrafomer を使ってコード化 フォルダを作成し移動 $ mkdir terraform $ cd terraform

    AWS のリソースを操作できるように provider の設定ファイルを作成 $ touch provider.tf AWS の provider の設定を書き込む( terraform という AWS profile を予め設定 し ておきます) provider "aws" { region = "ap-northeast-1" profile = "terraform" } 29
  19. 4. Terrafomer を使ってコード化 最新バージョンの Terraform に変更し初期化する $ asdf local terraform

    1.2.7 $ terraform init IAM ロール名を指定して Terraform のコードを生成する 「generated/aws/iam/」 配下に取り込んだコードが作成されます。 $ terraformer import aws --resources=iam --filter="Name=name;Value=IAM_ROLE_NAME" --profile=terraform Terraformer が作成した provider の設定を以前設定したものに合わせる $ cat provider.tf > generated/aws/iam/provider.tf 必要のないファイルを削除します $ rm -rf .terraform .terraform.lock.hcl provider.tf 30
  20. 4. Terrafomer を使ってコード化 Terraformer で生成された iam_role.tf は以下のような感じになっていると思います。 resource "aws_iam_role" "tfer--translate-function-dev-ap-northeast-1-lambdaRole"

    { assume_role_policy = <<POLICY { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" } POLICY inline_policy { name = "translate-function-dev-lambda" policy = "xxxxxxxxxxxxxxxxx" } managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess", "arn:aws:iam::aws:policy/TranslateFullAccess"] max_session_duration = "3600" name = "translate-function-dev-ap-northeast-1-lambdaRole" path = "/" tags = { STAGE = "dev" } tags_all = { STAGE = "dev" } } 31
  21. 4. Terrafomer を使ってコード化 tfstate ファイルのバージョンが 0.12.31 の状態になっているのでバージョンアップ させる terraform のバージョンを

    0.13.x にする $ cd generated/aws/iam $ asdf local terraform 0.13.7 0.13.7 のバージョンに変更しアップグレードコマンドを実行する $ terraform init $ terraform 0.13upgrade 実際に apply & tfstate をバージョンアップさせ問題ないことを確認する $ terraform apply 32
  22. 4. Terrafomer を使ってコード化 これで Terraform で IAM ロールの管理 もできるようになりました! 次は

    Terraform で管理させた IAM ロールを Serverless Framework で管理できる ようにします! <補足情報> Terraformer がサポートしている Terraform のバージョンは 0.13 。 でも…… Terraformer import は terraform 0.13.x は だけど Terraform 1.2.7 は M1 Mac だと 0.13.x 系のバージョンのインストールが出来ないので私が以前書いた記事(M1 Mac でそのバージョンの Terraform 使えないじゃないか!)を参考にして下さい。 バージョンが 0.13.x なのでバージョンアップはよしなにやってください。 33
  23. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 34
  24. 5. Serverless Framework → Terraform を連携する 連携方法については実は Serverless Framework の公式のブログ

    で解説されていま す! 詳しくはこちらの「The definitive guide to using Terraform with the Serverless Framework」を参照して下さい! こんな事が書かれています。 The SSM parameter store is a great way to share the values between the two systems. Terraform provides an SSM parameter resource that you can use to write arbitrary SSM keys. You can then consume those keys in your serverless.yml via the ${ssm:...} reference. 36
  25. 5. Serverless Framework → Terraform を連携する 現在の構成では IAM ロール は

    Terraform で管理するため、Serverless Framework で対象の IAM ロール を参照できるようにします。 ドキュメントを参考にすると ssm というキーワード を使うことで AWS Systems Manager Parameter Store を参照できる ようになるため、AWS Systems Manager Parameter Store に AWS Lambda で使用する IAM ロール の ARN を設定 すれば連携ができそうです。 イメージとしては以下のような感じです。 provider: iam: role: ${ssm:/translate/iam_role/lambda_function_role_arn} 37
  26. 5. Serverless Framework → Terraform を連携する Terraform で AWS Systems

    Manager Parameter Store を作成します。 parameter_store.tf ファイルを作成してそこに記述していきましょう! AWS Systems Manager Parameter Store のファイルを作成する $ cd generated/aws/iam $ touch parameter_store.tf AWS Systems Manager Parameter Store の記述をします 「aws_iam_role_resource_name」に関しては Terraformer で自動で設定されているはずな のでそちらに書き換えてください。 resource "aws_ssm_parameter" "lambda_function_iam_role" { name = "/translate/iam_role/lambda_function_role_arn" type = "String" value = aws_iam_role.aws_iam_role_resource_name.arn } 38
  27. 5. Serverless Framework → Terraform を連携する Serverless Framework の serverless.yml

    の provider に iam の箇所を追記しま す。 provider: name: aws runtime: python3.8 region: ap-northeast-1 profile: serverless endpointType: regional iam: role: ${ssm:/translate/iam_role/lambda_function_role_arn} 実際に連携出来ているか試すために Terraform の IAM ロールの name を書き換えて terraform apply した後、 Serverless Framework で serverless deploy してみまし ょう! 39
  28. 5. Serverless Framework → Terraform を連携する これで Serverless Framework →

    Terraform の連携が完了しました! Terraform で作成したものを AWS Systems Manager Parameter Store に設定して それを Serverless Framework で読み込むことで連携出来ます。 では最後に Terraform → Serverless Framework の連携方法を見ていきましょう! 40
  29. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 41
  30. 6. Terraform → Serverless Framework を連携する AWS CloudFormation の Stack

    が出力した値 を Terraform 側で読み込むこと で Serverless Framework が作成したリソースにアクセスすることができるようになり ます。 43
  31. 6. Terraform → Serverless Framework を連携する Terraform 側で以下のように記述することで data として扱えるようにします

    data "aws_cloudformation_export" "lambda_function_qualified_arn" { name = "sls-translate-function-dev-TranslateLambdaFunctionQualifiedArn" } 呼び出す時は以下のような感じで呼び出します。 value = data.aws_cloudformation_export.lambda_function_qualified_arn.value 44
  32. 6. Terraform → Serverless Framework を連携する Terraform → Serverless Framework

    の連携を紹介しましたが個人的にはまだどう いった感じで使用するのがいいのかピンときていない状況です。 ここでは AWS CloudFormation の Stack が出力した値 を Terraform 側で読み込む こと で Serverless Framework が作成したリソースにアクセスすることができると いうことだけをとどめておくぐらいでいいかなと思っています。 何かいい活用方法があれば教えて下さい! 45
  33. アジェンダ 1. 題材 2. Terraform と Serverless Framework で管理するもの 3.

    Serverless Framework を使ってコード化 4. Terrafomer を使ってコード化 5. Serverless Framework → Terraform を連携する 6. Terraform → Serverless Framework を連携する 7. まとめ 46
  34. 7. まとめ 今日のまとめになります。 Terraform と Serverless Framework を相 互連携させるには…… Serverless

    Framework → Terraform では AWS Systems Manager Parameter Store を使おう! Terraform → Serverless Framework では AWS CloudFormation の Stack が出力した値 を Terraform 側で読み込む! 47
  35. 7. まとめ 何を Terraform で管理させ何を Serverless Framework で管理させる のか? 今回紹介させて頂いたものは

    開発環境を主軸において管理させる もの でした。 途中で紹介した Serverless Framework のブログ記事では 共有のイン フラは Terraform で管理 し アプリケーション固有のインフラは Serverless Framework で管理する と良いでしょうと書かれていま す。とてもバランスが良さそうです! 49
  36. 7. まとめ 今日の発表では Terraform と Serverless Framework のコードは簡略 化した形で紹介しました。 https://github.com/dodonki1223/translate

    のリポジトリではローカ ルの開発環境も整えつつ私が実装したものがありますのでよければ参考 にして下さい! 50