CloudFormationを使ってlambda(node.js)環境を構築する

# はじめに
aws環境に成果物をデプロイする際の、デプロイ自動化の手段としてaws CloudFormationがある。本記事ではCloudFormationを使って、lambda(node.js)環境を構築する方法について記述する。

# CloudFormationとは
CloudFormationとは、テンプレートファイルと呼ばれる設計図みたいなものに基づいて自動的にawsの各種サービスをプロビジョニング（生成）してくれるサービスである。テンプレートファイルを一度書いてしまえば、同一のシステムを何度でも再現することが可能。手動でシステムをプロビジョニングすると時間がかかったりミスするおそれがあるため、効率と正確性の観点でCloudFormationの活用は有用である。

# CloudFormation動作の流れ
![スクリーンショット 2018-11-09 16.33.47.png](https://qiita-image-store.s3.amazonaws.com/0/191873/890fba01-9922-9f60-0863-26d9bf9f0f26.png)

CloudFormationはs3バケット上に置かれたテンプレートファイルを読み込み、そのテンプレートに基づき動作する。同じくs3バケットに置かれたlambda関数のアーカイブ(zip)ファイルとテンプレート上で指定されたパラメータに基づきlambdaを生成する。

# テンプレートファイル
テンプレートファイルとは以下のようなyaml（あるいはjson形式）で記述される。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  HelloWorldLambdaFunction:
    Type: AWS::Lambda::Function
    Properties: 
      FunctionName: lambda-function-name
      Handler: index.handler
      Role: arn:aws:iam::1234567890:role/LambdaRole
      Runtime: nodejs8.10
      Timeout: 10
      Code:
        S3Bucket: bucket-name
        S3Key: app/deploy/lambda.zip
      Tags:
        -
          Key: COST
          Value: app-lambda
```

これはnodejs8.10で動くlambda関数を作成するためのテンプレートである。zipファイルは、node.jsプロジェクトをzip化したもの（コンソール上で手動でアップロードするファイルと同じ）。テンプレート記述の内容は、手動でlambdaをデプロイした経験があれば問題なく分かる内容である。
RoleのARNはIAMコンソールで作成済みのRoleを参照することで確認することができる。

テンプレートファイル記述のリファレンスは以下参照
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-reference.html

テンプレートリファレンス　lambda function
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html

# コンソールでCloudFormationを利用する
テンプレートファイルとlambdaアーカイブファイルをs3に配置した上で、ブラウザからawsのCloudFormationコンソールを開いて、上述のテンプレートファイルのパスを指定して実行すればスタック(今回のケースではlambda関数)が作成される。

# aws-cli経由でCloudFormationを利用する
上述のコンソールを使うやり方だとテンプレートファイルのパスなどCloudFormationのパラメータを手動で設定する必要がある。それも自動化してさらに高度な再現性を得るにはaws cli経由でCloudFormationを操作する。

以下にaws cli経由でCloudFormationのスタックを作成する一例を示す。aws cliは自身のローカルPC、ec2、CodeBuild等の環境で実行可能。

```
aws cloudformation create-stack --stack-name sample-stack --template-url https://s3-ap-northeast-1.amazonaws.com/bucket-name/template/template.yaml --tags Key=COST,Value=sample-stack --region ap-northeast-1

aws cloudformation wait stack-create-complete --stack-name sample-stack
aws cloudformation describe-stacks --stack-name sample-stack
```

- create-stackでスタックの作成開始
- waitでcreate-stack動作完了を待つ
- describe-stacks で指定したスタックの状態を確認

スタックは同名のスタックが既に存在する場合、creta-stackできずエラーとなる。
そのため、同名のスタックが存在し得る場合は、スタックのアップデートか一度スタック削除してから生成する。
以下は一度削除してからcreate-stackしている例。

```
aws cloudformation delete-stack --stack-name sample-stack
aws cloudformation wait stack-delete-complete --stack-name sample-stack

aws cloudformation create-stack --stack-name sample-stack --template-url https://s3-ap-northeast-1.amazonaws.com/bucket-name/template/template.yaml --tags Key=COST,Value=sample-stack --region ap-northeast-1

aws cloudformation wait stack-create-complete --stack-name sample-stack
aws cloudformation describe-stacks --stack-name sample-stack

```

以上でaws-cli経由でCloudFormationを使ってlambdaのデプロイが実行される。


# まとめ
aws-cli経由でCloudFormationでスタック作成できるようにしておくと、JenkinsやCodeBuild等から実行することができるようになり、デプロイ作業が自動化される。

# awsで開発作業を自動化するのまとめ記事
本記事はawsで開発作業を自動化するシリーズの1つです。その他の記事については以下を参照ください。
[aws環境でnode.js、lambda、CodeCommit、CodeBuild、CloudFormation、CodePipelineを使って開発作業を自動化する](https://qiita.com/kyuaz/items/704efb51bce59f21c002)