##AWS SAMとは
AWS サーバーレスアプリケーションモデル (SAM、Serverless Application Model) は、サーバーレスアプリケーション構築用のオープンソースフレームワークです。迅速に記述可能な構文で関数、API、データベース、イベントソースマッピングを表現できます。リソースごとにわずか数行で、任意のアプリケーションを定義して YAML を使用してモデリングできます。
テンプレートのYMALファイルに構成を記載することで、
サーバーレスアプリケーションをまとめて管理できます。
インストール方法はこちら↓
##テンプレートの構成について
基本的に必須なのは、TransformとResourcesのみ。
Resourcesの論理IDにAPI GatewayやLambdaなどの構成を記載していきます。また論理IDはテンプレート内で一意となる必要があります。
論理名でテンプレートの他の部分のリソースを参照したりできます。
ちなみにこの論理IDは、CloudFormationのイベントの論理IDに紐づきます。
※誤字があったりでデプロイ後、変えるのはやめましょう(戒め)
今回は、LambdaExecutionRoleとWebSecurityGroupも一緒に作成してみます。
以下、yamlファイルです。
なんとなく感じを掴んでもらえればと思います。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: sample API
Globals:
Api:
OpenApiVersion: 3.0.2
Resources:
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
ManagedPolicyArns:
- !Sub 'arn:aws:iam::aws:policy/AmazonVPCFullAccess'
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "sample API SecurityGroup"
GroupName: sample-API-SecurityGroup
VpcId: vpc-XXXXXXXX
RestApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
OpenApiVersion: 3.0.2
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: ./sample-api-dev-swagger-apigateway.yaml # API Gatewayの構成のパス
SampleFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: sample-function
Handler: lambda_function.lambda_handler
Runtime: python3.8
Role: !GetAtt LambdaExecutionRole.Arn # Roleを紐付け
CodeUri: ./sample-function/ # Lambdaのコードのパス
Description: ''
MemorySize: 128
Timeout: 25
Events:
Api:
Type: Api
Properties:
RestApiId: !Ref RestApi # RestApiと紐付け
Path: '/v1/sample-function/{param}'
Method: GET
VpcConfig:
SecurityGroupIds:
- !Ref WebSecurityGroup # WebSecurityGroupと紐付け
SubnetIds:
- subnet-XXXXXXXX
- subnet-XXXXXXXX
Environment:
Variables:
ID: 1234 # 環境変数その1
PASS: hogehoge # 環境変数その2
Tags:
STAGE: dev
Layers:
- Ref: SampleLayers # Layersと紐付け
SampleLayers:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: sample-layers
Description: Sample API Resource Layer
CompatibleRuntimes:
- python3.8
ContentUri: ./sample-layers # Layersのパス
YAMLの短縮記法で論理IDを指定していきます。
OpenApiVersionの記載については、こちらも合わせてどうぞ
##Makefileでデプロイできるようにする
CI的にもなるべく簡単にデプロイできるようにしたいです。
開発環境と本番環境で、設定値などが分けられる様にもします。
feq ($(ENV), dev)
PROFILE := sample-api-dev
STACK_NAME := sample-api-dev-stack
BUCKET_NAME := sample-api-dev-bucket
TEMPLATE := template_dev.yaml
TEMPLATE_OUT := template_dev_output.yaml
else ifeq ($(ENV), prd)
PROFILE := sample-api-prd
STACK_NAME := sample-api-prd-stack
BUCKET_NAME := sample-api-prd-bucket
TEMPLATE := template_prd.yaml
TEMPLATE_OUT := template_prd_output.yaml
endif
check:
@echo Profile: $(PROFILE)
@echo Stack Name: $(STACK_NAME)
@echo Bucket Name: $(BUCKET_NAME)
@echo Template File: $(TEMPLATE)
make_bucket:
aws s3 mb s3://${BUCKET_NAME} --region ap-northeast-1 --profile ${PROFILE}
encrypt_bucket:
aws s3api put-bucket-encryption --bucket ${BUCKET_NAME} --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
bucket: make_bucket encrypt_bucket
get_cert:
aws s3 --profile ${PROFILE} cp s3://${BUCKET_NAME}/certs/ ./sample-layers/certs/ --recursive
del_cert:
rm -rf ./sample-layers/certs/
pac:
aws cloudformation package \
--template ${TEMPLATE} \
--output-template-file ${TEMPLATE_OUT} \
--s3-bucket ${BUCKET_NAME} --profile ${PROFILE} \
deploy:
aws cloudformation deploy \
--template-file ${TEMPLATE_OUT} \
--stack-name ${STACK_NAME} \
--capabilities CAPABILITY_NAMED_IAM --profile ${PROFILE} \
delete:
@echo "Are you sure to delete the stack ${STACK_NAME}? [y/N] " && read ans && [ $${ans:- N} = y ]
aws cloudformation delete-stack --stack-name ${STACK_NAME} --profile ${PROFILE}
all: check get_cert pac deploy del_cert
利用する環境のプロファイルを設定し、
環境ごとに分けられるようにします。
$ aws configure --profile sample-api-dev
AWS Access Key ID [None]: アクセスキーID
AWS Secret Access Key [None]: シークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]:
設定の確認↓
$ aws configure list
[sample-api-dev]
aws_access_key_id=アクセスキーID
aws_secret_access_key=シークレットアクセスキー
初めのみバケットを作成します。
※2回目以降は重複エラーになります。
$ make bucket ENV=dev
デプロイします。
$ make all ENV=dev
Profile: sample-api-dev
Stack Name: sample-api-dev-stack
Bucket Name: sample-api-dev-bucket
Template File: template_dev.yaml
Template Output File: template_dev_output.yaml
Are you sure to deploy with these settings? [y/N]
以下で完了
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - sample-api-dev-stack
##最終的な構成
sample-app
│ .gitignore
│ Makefile
│ README.md
│ sample-api-dev-swagger-apigateway.yaml # 開発用API Gatewayのテンプレート
│ sample-api-prd-swagger-apigateway.yaml # 本番用API Gatewayのテンプレート
│ template_dev_output.yaml # デプロイ時に作成されたアウトプットファイル S3のロケーションなどが記載される。
│ template_dev.yaml # 開発用のテンプレート
│ template_prd.yaml # 本番用のテンプレート
│
├─ sample-function # Lambda関数
│ └─ lambda_function.py
│
└─ sample-layers
##参考