アプリとサービスのすすめ

アプリやIT系のサービスを中心に書いていきます。たまに副業やビジネス関係の情報なども気ままにつづります

Terraform × ApexでLambdaとCloudwatchログのスケジュールを管理してみた【機械学習・AWSインフラ】

Terraformが人気のインフラ管理ツールということで是非習得したかったので、TerraformとそのラッパーのApexを使って、LambdaとCloudwatchログのスケジュール管理をしてみた。

Apexを使えばLambda管理がラクにできるので、運用をイメージしてTerraformでlambdaを含めたAWSインフラを管理するまでのログをまとめてく。

目次
1.Terraformで管理するインフラの全体像
2.コード&ファイル
3.実行コマンド
4.まとめ

1.Terraformで管理するインフラの全体像

AWSインフラリソースの全体像


TerraformとApexで管理するAWSインフラの全体像を表すと下の図の通り。
f:id:trafalbad:20190518092716j:plain


Apexを使うと嬉しいことは2つ。

・Lambdaの管理がラクになる
terraformでLambdaを管理するには、

AWSのオブジェクト管理(Lambda Function、IAM、triggerのためのCloudWatch Eventsなど)

②Lambda関数のソースコード

③Lambda関数のソースコードに依存するライブラリたち

ソースコードとライブラリを固めたzip

が必要だけど、Apexなら②~④をまとめてやってくれる。


・Lambda用のコードをS3バケットではなく、直接Lambdaにアップロードできる
Apexが上の②〜④をやってくれるおかげで、zipを入れるS3バケットの管理や、terraformでのzipファイルの管理が必要なくなる。




運用イメージ


運用イメージは
・CloudWatchログのログをLambdaで「他のリソース」に送りつけること
を想定してる。


例1.Datadog docsにCloudWatchログのログをLambdaで送りつける
f:id:trafalbad:20190518083246p:plain



例2.ElasticseachにCloudWatchログのログをLambdaで送りつける
f:id:trafalbad:20190518083306j:plain


2.コード

ディレクトリ構成

./project.json # プロジェクト全体の定義
./functions/datadog_logs/function.json # 関数の定義
./functions/datadog_logs/datadog_logs.py # Lambdaで実行するコード(今回はPythonのサンプル)
./infrastructure/prod/main.tf # Terraformで管理するAWSリソースの定義</div>

functions配下の「datadog_logs」フォルダはLambda関数名に合わせる。
またinfrastructure配下の「prod」フォルダは環境の意味(prod=env)で、環境ごとにLambdaを作り分けられるApexの機能。

f:id:trafalbad:20190518083333p:plain



project.json


{
    "name": "event_driven_job",
    "description": "event driven job",
    "memory": 1024,
    "timeout": 120,
    "role": "arn:aws:iam::{各自のAWS Account ID}:role/datadog_logs",
    "environment": {}
}

fuction.jsonとproject.jsonの共通項目はproject.jsonに書けば上書きできるので、role、memory、timeoutとかの共通項目はproject.jsonに書いた。



function.json


{
    "description": "datadog_logs",
    "runtime": "python3.6",
    "handler": "datadog_logs.lambda_handler",
    "environment":
    {
        "ENV": "dev"
    }
}

“runtime”と”handler"さえ良ければOK。あと、関数名は「datadog_logs」。



datadog_logs.py


def lambda_handler(event, context):
    json = {"statusCode": 200, "body": "hello world"}
    return json

Lambda関数用のpython.3.6のサンプルファイル。今回の記事ではほとんど関係ないのでテキトーに作った。



main.tf(resource、variableとかの解説)


・インフラ管理リソース設定
terraform

provider “aws

・Apexに必要
variable "apex_function_datadog_logs" {}


・IAMロールの作成に必要
resource "aws_iam_role" “datadog_logs_lambda_role"

data "aws_iam_policy_document" "datadog_logs_lambda_policy_doc"

resource "aws_iam_role_policy" “datadog_logs_lambda_policy"


・Cloudwatchログのログの出力先
output “datadog_logs_lambda_role"


・Cloudwatchログのロググループ名を定義
data "aws_cloudwatch_log_group" “log_group"


・Cloudwatchログからのログのストリーム設定
resource "aws_cloudwatch_log_subscription_filter" “datadog_logs_filter"


・Lambdaへのアクセス許可
resource "aws_lambda_permission" “datadog_logs_filter"





3.実行コマンド

1.セットアップ

MacにApexをinstall

$ curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh

・cloudwatchログにロググループ作成(参考サイト
グループ名→「datadog_logs」



・東京regionのS3バケット「apex-test-bucket」を作る


AWS環境変数の設定

$ export AWS_ACCESS_KEY_ID=****
$ export AWS_SECRET_ACCESS_KEY=****
$ export AWS_DEFAULT_REGION=ap-northeast-1
$ export AWS_REGION=ap-northeast-1


2.terraformのバックグランド初期化


$ apex infra init


3.IAMロールの作成


$ apex infra apply -target aws_iam_role.datadog_logs_lambda_role -target aws_iam_policy_document.datadog_logs_lambda_policy_doc -target aws_iam_role_policy.datadog_logs_lambda_policy

-targetオプションではmain.tfのIAMロール作成に必要なリソースを指定してる。

実行後は、IAMロールで「data_logs (AWS サービス: lambda)」ができてる。

f:id:trafalbad:20190518083430p:plain




4.Lambdaのデプロイ


$ apex deploy

S3やcloudwatchログが紐付いたLambda関数が出来てる。関数名は”{{.Project.Name}}_{{.Function.Name}}”。

f:id:trafalbad:20190518083510p:plain




5.残りのAWSリソース(Lambdaのトリガー)のデプロイ


$ apex infra apply

Lambda関数のトリガーにcloudwatchログが追加されてる
f:id:trafalbad:20190518083548p:plain




6.後片付け


$ apex infra destroy
$ apex delete

IAMロール & Lambda関数がキレイに破壊されてる。

f:id:trafalbad:20190518083805j:plain





4.まとめ

terraformコマンド集

# terraformインストール
$ brew install terraform

# バージョン確認
$ terraform --version
$ terraform init   

# インフラ環境を新しく作るため、変更内容を確認
$ terraform plan

# planで確認した内容が実行
$ terraform apply

# 進行状況の確認
$ terraform show

# リソースの全削除
$ terraform destroy


理解するためにやったこと



・terraformでEC2だけ作ってみる

・Lambdaにzipファイルをアップロードしてみる

GUIでCloudWatch イベントでAWS Lambda 関数をスケジュールしてみる

・サイト「Apex+Terraformでサーバレスアーキテクチャをフルコード化」を一通りやってみる



参考サイト



Apex+Terraformでサーバレスアーキテクチャをフルコード化

Providers - Terraform by HashiCorp(Terraform公式サイト)

Apex公式サイト