0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CloudFormation、キミにきめた!

Posted at

0.はじめに

今年の7月にAWSアソシをギリで取得した初心者が、AWSでそれっぽいことをする奮闘記続きの更に続き。
CloudFormationの便利さは勿論、そこまでの道のりも整備されていて、感動。

       君に決めた_Cloud.png

1. やりたいこと

みんなが楽して、セキュアな仕組みを確実に実装できるようにしたい。
これがすべて。

  • 楽して:これでも充分楽なんだけど、それでももっと楽したいのが人間。
    • Lambdaに参考となるPythonコードをコピペしてきて…
    • VPCとかサブネットの設定もして…
    • API-GWも作成して…
    • おっと、APIのデプロイもしなきゃ…
  • 確実に実装:
    • 設定するVPCとか間違えそう
    • サブネットとか設定しなそう。

それを実現してくれるのが、CloudFormationくん。
AWSアソシにはちらっと登場してくる彼。
便利そうってことは知ってたけど、どのくらい便利かは知らなかった。
いざ。

2. できたもの(構成図+α)

構成図に手順を含めるとこんな感じ。
青枠部分が今回楽して作りたいAPIGWとLambda。

 ① 青枠のLambdaをテンプレ化して、
 ② それをS3にぶち込んで(※1)、
 ③ それをスタック作る際のインプットとする。:★
  ※1 構成管理ってなら、CodeCommitなんだろう。。

ユーザは★をやるだけ。
そうすると、テンプレに従って、青枠の部分が勝手に作られる、そんな動き。

slackAWSPOSTAPI-1-todo.png

3. どんな風に作ってったか。

元となるLambdaとAPI-GWは前の旅で、作成済の状態。ざっとこんな状態。

image.png

まずは、①のテンプレの元ネタを作ろう!

上記のLambdaの管理コンソール画面で、[アクション]→[関数のエクスポート]を選択すると、
以下2種類の形式でダウンロードできる。

image.png

ざっくり言うと、

  • AWS SAMファイル:上の設定した環境変数やタグといった設定値が、超絶シンプルまとまって記載されたテンプートファイル
  • デプロイパッケージ:ソースコードがZip化されたもの

今回は両方使う。
元ネタとしては、これで準備OK。
さらっと書いてるけど、これがあるのとないとでは、大違い。綺麗な道のり整備、助かります!

ちょっとだけカスタマイズする。

いくつかコネコネする。
なお、前の手順でダウンロードしたSAMファイルはこんな状態。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
  slackwebfiltertry:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.8
      CodeUri: .
      Description: ''
      MemorySize: 128
      Timeout: 3
      Role: >-
        arn:aws:iam::0000000000:role/service-role/slack-webfilter-try-role-xxxxxxx
      Events:
        Api1:
          Type: Api
          Properties:
            Path: /slack-webfilter-try
            Method: POST
      VpcConfig:
        SecurityGroupIds:
          - sg-xxxxxxxxxxxxxxx
        SubnetIds:
          - subnet-xxxxxxxxxxxxxxx
          - subnet-xxxxxxxxxxxxxxx
      Environment:
        Variables:
          POST_SLACKAPI_URL: >-
            https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.amazonaws.com/xxxxxxxxxxxxxxxxxx/share-postanytoslack-api
          WEB_HOOK_URL: >-
            https://hooks.slack.com/services/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx
      Tags:
        slack: 'true'

レッツ、コネコネタイム。

いや、待て待て。それぞれ何を定義してんのか分からんわ!(いや、なんとなく分かるかw)
ってことで、ブラックベルト。これは分かりやすい。
https://d1.awsstatic.com/webinars/jp/pdf/services/20190814_AWS-Blackbelt_SAM_rev.pdf

できそうなので、レッツ、コネコネ。

(1) 関数コード

CodeUriが、ローカルの状態なので、S3上のデプロイパッケージのパスに置き換える。
※前の手順でダウンロードしたデプロイパッケージをS3にぶち込んでおく。

(2) 作成するLambdaの関数名

デフォルトだと関数名はCloudFormationのマクロ側で勝手に設定されてしまう。
名前は大事だ。
ユーザに自分の関数名を入力してもらうために、
FunctionNameを追記して、かつパラメータとして扱う記述をする。
それがParameters:の部分。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Parameters:
  FunctionName:
    Type: String
    Description: Enter the purpose of the Lambda-function as a name.
Resources:
  slackwebfiltertry:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.8
      CodeUri: s3://XXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.zip
      FunctionName: !Sub "${FunctionName}"
      Description: ''
      MemorySize: 128
      Timeout: 3
(略)

(3) プロキシ統合

今回のAPIは、管理コンソールの図のように「Lambdaプロキシ統合を使用」しない版で作成したい。(チェックない状態)
※上でダウンロードした状態のままだと、プロキシ統合した版(チェックある状態)で作成されてしまう。

image.png

こちらと、ブラックベルトを参考に。
https://dev.classmethod.jp/articles/cloudformation_template_for_api_gateway_integration_to_lambda/
※プロキシ統合したい場合⇒ type: "aws_proxy"、したくない場合⇒type: "aws"

Black Beltより
image.png

EventsブロックのPathとMethodいらないかな?って思ってけど、
必須らしく、下の方にあるpathsとの違いはよく分かってない。。。

(略)
      Events:
        Api1:
          Type: Api
          Properties:
            RestApiId: !Ref posttoslackApi
            Path: /posttoslack
            Method: POST
      VpcConfig:
(略)
      Tags:
        slack: 'true'
  posttoslackApi:
    Type: 'AWS::Serverless::Api'
    Properties:
      StageName: prod
      DefinitionBody:
        swagger: "2.0"
        paths:
          /posttoslack:
            post:
              x-amazon-apigateway-integration:
                uri: 
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${slackwebfiltertry.Arn}/invocations
                httpMethod: "POST"
                type: "aws"

ということで、この3つでテンプレートは完了!
S3にぶち込む。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Parameters:
  FunctionName:
    Type: String
    Description: Enter the purpose of the Lambda-function as a name.
Resources:
  slackwebfiltertry:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: lambda_function.lambda_handler
      Runtime: python3.8
      CodeUri: s3://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.zip
      FunctionName: !Sub "${FunctionName}"
      Description: ''
      MemorySize: 128
      Timeout: 3
      Role: >-
        arn:aws:iam::xxxxxxxxx:role/service-role/slack-webfilter-try-role-xxxxxxx
      Events:
        Api1:
          Type: Api
          Properties:
            RestApiId: !Ref posttoslackApi
            Path: /posttoslack
            Method: POST
      VpcConfig:
        SecurityGroupIds:
          - sg-xxxxxxxxx
        SubnetIds:
          - subnet-xxxxxxxxx
          - subnet-xxxxxxxxx
      Environment:
        Variables:
          POST_SLACKAPI_URL: >-
            https://xxxxxxxxxxxxxxxxxx.amazonaws.com/xxxxxxxxxxxxxx/share-postanytoslack-api
          WEB_HOOK_URL: >-
            https://hooks.slack.com/services/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxx
      Tags:
        slack: 'true'
  posttoslackApi:
    Type: 'AWS::Serverless::Api'
    Properties:
      StageName: prod
      DefinitionBody:
        swagger: "2.0"
        paths:
          /posttoslack:
            post:
              x-amazon-apigateway-integration:
                uri: 
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${slackwebfiltertry.Arn}/invocations
                httpMethod: "POST"
                type: "aws"

4. 使ってみる(ユーザ向けの手順ってところ)

はい、かんたーーーん!

(1) スタックの作成

CloudFormationから、[スタックの作成]→[新しいリソースを使用(標準)]を選択する。
image.png

(2) テンプレートを選択する

S3にぶち込んでるテンプレートのURLを指定する。
image.png

(3) 名前を記入する

スタックの名前とそこから作成されるLambdaの関数名をそれぞれ記入する。
image.png

(4) スタックオプション

このスタックはSlack関連で使ってるってのを分かりやすくするため、タグ付けしておく。
image.png

(5) すべてにチェック

すべてチェックをつけて、スタックの作成を実行する。
image.png

(6) 終わったら確認

[スタックの情報]でステータスがCREATE_COMPLETEになってることを確認する。
※失敗するとROLLBACK_COMPLETEになる。

作成したLambdaやAPIGWは[リソース]から参照できる。
image.png

また、[テンプレート]から、SAMと、処理されたテンプレートも見れるため、詳細を知りたい場合は結構参考になる。
いや、分からにくいって場合は、[デザイナーで表示]を選択すると、
こんな感じにグラフィカルに表現してくれる。うーん、優しい。

image.png

(7) 作成されたLambda修正

勿論テンプレベースなので、Lambdaのコードなどを自分用に修正していく。
これで終わり。

5. まとめ

こういった情報はWebに沢山あるし、GUIでほぼ出来ちゃうので仕組み作りも楽しめる。
もっとAWSと仲良くなる旅にでよう、かな。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?