AWS初心者がCloudFormationでLambdaをデプロイしてみた

毎度どうも！
AWS初心者のくせにAWS使用率100％の会社に転職したSATO論外です！
今回は上司からせっかくAWS触るんだったらLambdaとCloudFormation使ってサーバレスフレームワークを
作ってみたらとのアドバイスがありましたのでこの機会に挑戦してみます！

# そもそもLambdaとCloudFormationってなんだい？
##AWS Lambda
調べたら、Lambdaはなんらかのイベントが起きたら、あらかじめ設定した処理（機能＝関数）が実行される環境とのことです

　○AWSの公式ページ
　　[AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)
　○その他参考にしたページ(分かりやすい！！)
　　[「Lambda」ってなにがスゴイんですか？](https://www.bit-drive.ne.jp/managed-cloud/column/column_14.html)

Lambdaを使うと何がすごいか・・・
つまりこういうことらしいです
　・アプリケーションを実行するためにわざわざ**EC2のインスタンス**などのWEBアプリケーションサーバーを
　　**立てる必要がない**！
　・DynamoDBとか使用して**データベースアクセスもできる**
　・料金も処理が動いた時間だけ課金されるので**コスト削減**になる
　
Lambdaを使えばわざわざWEBサーバーも作らずに簡単に高機能な物を作れちゃいそうですね！

##CloudFormation
○AWSの公式ページ
　[AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)
○その他参考にしたページ
　[CloudFormation超入門](https://dev.classmethod.jp/beginners/chonyumon-cloudformation/)
　[CloudFormationで環境構築を自動化する](https://www.atmarkit.co.jp/ait/articles/1408/25/news014.html)

いまいちAWSの公式ページの説明だと分かりにくかったですが、他のページを参考にしたところ
ざっくり言えば
`自分が作りたい環境を定義したファイルを作って、自動的にAWS上で作りたい環境を用意してくれるサービス`
とのことです。

AWSさん曰く以下がすごいことらしいです！
　・アプリケーションの実行に必要なリソースの作成および相互接続が、単一のEC2やRDSインスタンスを作成するのと
　　同じくらい簡単！
　・テンプレートを再利用してリソースをいつでも繰り返しセットアップできる（一度だけリソースを記述すれば複数の
　　リージョンで同じリソースを何度でも作れる！！）

　これはなかなか素晴らしそうなサービスです！
　是非是非ものにしたい！

##まず実行するPythonファイルをアップロードする
Lambdaで使用するファイルは以下の形です（LambdaのHelloWordの内容そのままです）

```test.py
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```
上のファイルをS3にzipファイルにしてアップロードしておきます。
権限の設定などが必要そうでしたので以下を参考にしました。
[Python 用の AWS Lambda デプロイパッケージを作成するには、どうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/build-python-lambda-deployment-package/)

##CloudFormation用のテンプレートファイルを作成する
作成するテンプレートはjson/yamlどちらでも良いそうです。
以下を参考にして作っていきます
[AWS CloudFormation:テンプレートの分析](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html)
[CloudFormationでLambda関数デプロイ(超初歩)](https://qiita.com/da-sugi/items/d2ba119a0e35ad1b352e)

```LambdaTest.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: "sample of cloudformation template for deploying a lambda function form S3."
Resources:
  HelloSample:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        S3Bucket: '★zipをアップロードしたS3bucket'
        S3Key: '★zipのフルパス'
      Description: 'LambdaTest'
      FunctionName: 'cloudformation-lambda-test'
      Handler: 'test.lambda_handler'
      Role: !GetAtt 
        - 'LambdaExecutionRole'
        - 'Arn'
      Runtime: 'python3.8'
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Principal:
              Service:
                - 'lambda.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
            ManagedPolicyArns:
              - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
```
参考先のページとほとんど一緒ですがPythonを3.8に・ManagedPolicyArnsにAWSLambdaBasicExecutionRoleを
追加しています。

○AWSLambdaBasicExecutionRole：(既存または新規の IAM 管理ポリシーを新規IANに追加
　参照は以下を参照
　[AWS CloudFormation で IAM 管理ポリシーを IAM ロールに添付する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudformation-attach-managed-policy/)

○細かいプロパティについては以下を参照
　[AWS::Lambda::Functionのプロパティ](https://qiita.com/da-sugi/items/f643a4418cde920daf6f)

実際にこれをアップロードしていきます！

##CloudFormationにテンプレートをアップロードしてみた！
 - コンソール画面の`サービス`から`CloudFormation`を選択します。
 - `スタックの作成`をクリック  
 - `テンプレートの準備完了`・`テンプレートファイルのアップロード`を選択、ファイルの選択から作成したファイルを  アップロードして`次へ`をクリック 
<img width="1016" alt="スクリーンショット 2020-03-10 17.27.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/5f865a95-f613-0eca-b34d-38d2eceb90fc.png">
 - `スタックの名前`を入力して`次へ`をクリック     
 - スタックオプションの設定については既存のままで`次へ`をクリック
 - 一番下にIAMリソース作成に関する承認があるのでチェックして`スタックの作成`をクリック
<img width="1025" alt="スクリーンショット 2020-03-10 17.39.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/00a43a58-1be1-1d9d-a722-c9b6ae78dc27.png">
 - 無事作成されるとイベントに結果が表示されます！
<img width="966" alt="スクリーンショット 2020-03-10 17.42.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/ba777530-f71b-aecb-3839-8c616f8398ce.png">

今回は無事作成された様です！！

##作成されたLambda Functionをみてみる
 - `リソースタブ`に作成されたリソースが表示されていますので作成したLambdaFunctionをクリック
 - 無事 関数コード内にアップロードしたコードが適用されています！
<img width="1480" alt="スクリーンショット 2020-03-10 17.46.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/34242989-15d7-8e40-8e09-066dc05b1ce9.png">

 - 右上の`テスト`からして新規テストを作成して実行してみます
![スクリーンショット 2020-03-11 9.06.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/331c40bb-ca71-cef0-0ae3-ec8621422298.png)
無事テストが成功しました！  
 - `アクセス権限タブ`をクリックして登録した権限があるか見てみます
<img width="998" alt="スクリーンショット 2020-03-10 17.49.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563324/66fd6b38-0aba-3bb2-3a86-73447039f3af.png">

コードのアップロードも権限設定もうまく行った様です！
ちなみに`ManagedPolicyArns`の設定を行わない場合はアクセス権限タブをみようとするとErrになりました。

##やってみての感想
テンプレート化できるのはなかなかに良さげです！
変更・更新もやってみましたが一度テンプレを作ってしまえばかなり楽です！！
ただし、初回はYAMLでの記載で少しはまったりしました、、、
あとIAMの設定がやっぱりわかっていない気がするのでもうちょい勉強します。。。

##その他参考にしたページ
[VSCodeでAWS CloudFormation をYAMLで書くための個人的ベスト設定](https://qiita.com/yoskeoka/items/6528571a45cd69f93deb)