はじめに
この記事は 「ハンズラボ Advent Calendar 2018」 22日目の記事です。
業務でAWSを利用することになったため、いろいろ自動化したいと思ってServerless Frameworkについて調べた内容をまとめました。
具体的には、Serverless Frameworkを使って以下の作業を行なっていきます。
- 事前準備(stage, profile, regionなどの設定)
- VPCの作成
- InternetGatewayの作成
- EIPの作成
- NatGatewayの作成
- Private Subnetの作成
- Public Subnetの作成
- APIGateway(Public Subnet)の作成
- Lambda(Private Subnet)の作成
- Serverlessでdeployしてみる
- Labmdaを実際に実行してみる
- 最後に
なお、本記事はAWSを初めて2ヶ月弱。
Serverless Frameworkを使い出して1週間の状態でいろいろ調べた結果をまとめた内容になっています。
このため、不備などあればぜひコメントで教えていただけるとうれしいです!
1. 事前準備(stage, profile, regionなどの設定)
今回は東京リージョンで、python3.7を指定して環境構築を行なっていきます。
profileは適宜ご自身の環境のものを利用してもらえればと思います。
また、serverless-python-requirements
pluginも利用しますので、インストールをお願いします。
provider:
name: aws
stage: ${opt:stage, 'stg'}
profile: serverless-sample-${self:provider.stage}
region: ap-northeast-1
runtime: python3.7
timeout: 30
memorySize: 128
versionFunctions: false
environment:
TZ: Asia/Tokyo
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
prefix: ${self:service}-${self:provider.stage}
1. VPCの作成
Resources配下に以下を追記します。
今回はサンプル環境のため、DeletionPolicyにDelete
を指定しています。
# リソースの構築
resources:
Resources:
SampleVPC:
Type: AWS::EC2::VPC
DeletionPolicy: Delete
Properties:
CidrBlock: 10.1.0.0/16
Tags:
- Key: Name
Value: SampleVPC
2. InternetGatewayの作成
Resources配下に以下を追記します。
SampleInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: SampleInternetGateway
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref SampleVPC
InternetGatewayId: !Ref SampleInternetGateway
3. EIPの作成
Resources配下に以下を追記します。
なお、他のResourceと同じようにPropertiesでTagsを試したところ、未サポートでしたのでコメントアウトしてあります。
EIPはVPC内に作成できる上限値があったりするので注意が必要です。
SampleElasticIp:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
# Tags:
# - Key: Name
# Value: SampleElasticIp
4. NatGatewayの作成
Resources配下に以下を追記します。
なお、AllocationId
の指定でしばらくハマりました。
当初は、!Ref SampleElasticIp
としていたのですが、この指定だとEIPのIPアドレスが取得されてしまい、NatGatewayの作成で失敗してしまうため、注意が必要です。
SampleNatGateway:
DependsOn: SampleElasticIp
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt SampleElasticIp.AllocationId
SubnetId: !Ref SamplePublicSubnet
Tags:
- Key: Name
Value: SampleNatGateway
5 PrivateSubnetの作成
Resources配下に以下を追記します。
SamplePrivateSubnet:
DependsOn: SampleVPC
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SampleVPC
# AvailabilityZone: ${self:provider.region}a
CidrBlock: 10.1.1.0/24
Tags:
- Key: Name
Value: SamplePrivateSubnet
SamplePrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SampleVPC
Tags:
- Key: Name
Value: SamplePrivateRouteTable
SamplePrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref SamplePrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref SampleNatGateway
SubnetRouteTableAssociationPrivateSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SamplePrivateSubnet
RouteTableId: !Ref SamplePrivateRouteTable
6. PublicSubnetの作成
Resources配下に以下を追記します。
SamplePublicSubnet:
DependsOn: SampleVPC
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SampleVPC
# AvailabilityZone: ${self:provider.region}a
CidrBlock: 10.1.11.0/24
Tags:
- Key: Name
Value: SamplePublicSubnet
SamplePublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SampleVPC
Tags:
- Key: Name
Value: SamplePublicRouteTable
SamplePublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref SamplePublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref SampleInternetGateway
SubnetRouteTableAssociationPublicSubnet:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref SamplePublicSubnet
RouteTableId: !Ref SamplePublicRouteTable
7. APIGatewayの作成
Resources配下に以下を追記します。
今回はサンプル環境のため、DeletionPolicyにDelete
を指定しています。
SampleApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
DeletionPolicy: Delete
Properties:
EndpointConfiguration:
Types:
- REGIONAL
Name: ${self:service}-${self:provider.stage}
8. SecurityGroupの作成
Resources配下に以下を追記します。
SampleSecurityGroup:
DependsOn: SampleVPC
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SecurityGroup for Sample Functions
VpcId: !Ref SampleVPC
9. Lambdaの作成
Resources配下に以下を追記します。
functions:
api:
# warmup: true
name: ${self:custom.prefix}-api
handler: lambda_function.lambda_handler
module: functions/api
vpc:
securityGroupIds:
- !Ref SampleSecurityGroup
subnetIds:
- !Ref SamplePrivateSubnet
events:
- http:
integration: lambda-proxy
path: helloworld
method: POST
cors: true
environment:
test: api-test
batch:
name: ${self:custom.prefix}-batch
handler: lambda_function.lambda_handler
module: functions/batch
vpc:
securityGroupIds:
- !Ref SampleSecurityGroup
subnetIds:
- !Ref SamplePrivateSubnet
environment:
test: batch-test
api
ディレクトリ配下にapi用のPythonスクリプトlambda_function.py
および、空のファイルrequirements.txt
を用意してください。
※ requirements.txt
はserverless-python-requirements
を利用している関係で必要となります。
import os
import logging
logger = logging.getLogger()
logLevel = logging.WARNING
def lambda_handler(event, context):
# Immediate response for WarmUP plugin
if event.get('source', None) == 'serverless-plugin-warmup':
logger.info('WarmUP - Lambda is warm!')
return 'Lambda is warm!'
return {
"statusCode": 200,
"body": "{\"message\": \"hello lambda api!\", \"input\": {\"test\": \"" + os.environ["test"] + "\"}}"
}
batch
ディレクトリ配下にbatch用のPythonスクリプトlambda_function.py
および、空のファイルrequirements.txt
を用意してください。
※ requirements.txt
はserverless-python-requirements
を利用している関係で必要となります。
import os
import logging
logger = logging.getLogger()
logLevel = logging.WARNING
def lambda_handler(event, context):
return {
"message": "hello lambda batch!", "input": {"test": os.environ["test"]}
}
10. Serverlessでdeployしてみる
profile
の設定などを確認して、以下のコマンドを実行します。
$ serverless deploy
1から環境を構築するため、数分かかります。
のんびり気長に待ってください。
以下のような結果が表示されれば環境構築成功です。
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (1.64 KB)...
Serverless: Uploading service .zip file to S3 (1.64 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.................................................................................
Serverless: Stack update finished...
Service Information
service: serverless-sample
stage: stg
region: ap-northeast-1
stack: serverless-sample-stg
api keys:
None
endpoints:
POST - https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/stg/helloworld
functions:
api: serverless-sample-stg-api
batch: serverless-sample-stg-batch
layers:
None
11. Labmdaを実際に実行してみる
11.1. functionのapi
を実行する
functionのapi
はapigatewayと関連付けしているため、作成されたendpointをcurlで実行してみます。
$ curl -X POST -H "Content-Type: application/json" https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/stg/helloworld
以下のようなレスポンスが返却されてくれば成功です。
{"message": "hello lambda api!", "input": {"test": "api-test"}}
11.2. functionのbatch
を実行する
functionのbatch
はapigatewayと関連付けしていないため、serverlessコマンドで実行します。
$ serverless invoke -f batch
以下のようなレスポンスが返却されてくれば成功です。
{
"message": "hello lambda batch!",
"input": {
"test": "batch-test"
}
}
12. 最後に
UnixやLinuxをオンプレ環境で構築したことなどはあったのですが、AWSでServerless Frameworkなどを使って環境構築などをすれば、再現性もあり非常に便利だなと感じました。
今後もAWSについてもっと勉強していきたいと思います。
「ハンズラボ Advent Calendar 2018」 の23日目は、@daisudaisuke さんの「Amazon Managed Blockchainでフリマアプリ作りたい Part1」です!