スライド/自分のサーバーレスアプリケーションの作り方 version 37

2022/11/20 16:30 by sinofseven
  :追加された部分   :削除された部分
(差分が大きい場合、文字単位では表示しません)
スライド/自分のサーバーレスアプリケーションの作り方
## 話すこと
- 自分がサーバーレスアプリケーションを作成する際に、どういった準備などをしているかをまとめてみた
- AWSのアーキテクチャをどうするとか、そういうことは今回話さない
- Lambda関数の実装部分も話さない

## index
1. 自己紹介
1. 使用するもの
1. 大まかな流れ
1. AWSアカウントを作成したらすること
1. 作成するリポジトリ
1. その他Tips

## 自己紹介
- 夏目 祐樹 (ナツメ ユウタ)
- クラスメソッド株式会社
  - CX事業本部 Delivery部
  - 自称 サーバーレス エンジニア
- 好きなAWSサービス
  - Lambda, DynamoDB, SQS
- 最近やってるゲーム
  - FF14 (万魔殿パンデモニウム零式: 煉獄編4層を先週クリア)
  - 空の軌跡 FC Evolution (ハードで6時間かけて序章終わらず)
  - 黎の軌跡II (金策とかやってたら、1章序盤)

## 使用するもの (1)
- AWS Organiztion
  - アプリケーション用のアカウントを作成するのに使う
    - 支払いをまとめることが目的
- github.com
  - コードのホスティング
  - Organization (フリープラン)
  - GitHub Actions (CI/CD)

## 使用するもの (2)
- Serverless Application Model (CloudFormation)
  - 原則としてAWSの管理はこれ
  - デプロイ等はsam-cliを使う
- make
  - タスクランナーとして使う
- Terraform (optional)
  - SSM ParameterのSecureStringなどを定義するのに使う
    - CloudFormationではSecureStringを作成できない
  - Terraform Cloudをバックエンドとして使う

## 大まかな流れ
1. AWS Organiztionで新しいアカウントを作る
   - 作成したら、普段アクセスするためのIAM Roleを作成する
1. GitHubでOrganizationを作成する
   - 作成しなくてもいいけど、後々の管理を楽にするため
1. 各種リポジトリを作成しつつ、実装する

## AWSのアカウントを作成したらすること 
- 普段使い用のIAM Roleを作成する
  - 基本的にSwitch Roleを使用して複数のAWSアカウントを扱っているため
  - `AdministratorAccess`
- LambdaなどのQuotaを確認する
  - 新規作成したアカウントではQuotaがデフォルト値よりも小さいことがあるので確認が必要

## 作成するリポジトリ (1)
1. prepare
   - CI/CDのために必要なリソースの作成をする
   - このリポジトリだけは手動でデプロイする
1. base (optional)
   - Lambda LayerやDocker Imageを作成する
1. secrets (optional)
   - 各種トークンなどSecretをSSM Parameterに保存する
   - Terraformで管理する

## 作成するリポジトリ (2)
4. cloud
   - アプリケーションに必要なLambdaやその他リソースを作成する
1. web (optional)
   - Webアプリのコードを置く

## 作成するリポジトリ (3) - `prepare` - (1)
- CI/CDに使うものを作成する
  - GitHub ActionsでAWSにアクセスするためのもの
    - `AWS::IAM::OIDCProvider`
    - `AWS::IAM::Role`
  - LambdaのArtifactなどを置くためのS3 Bucket

## 作成するリポジトリ (3) - `prepare` - (2)
GitHub ActionsでOIDCを使ったAssume Roleを行うためのProvider。  
誰が使おうとここ(のProperties)は同じ。  
***誰が使おうとここ(のProperties)は同じ。***

```yml
Resource:
  OidcProviderGitHub:
    Type: AWS::IAM::OIDCProvider
    Properties:
      Url: "https://token.actions.githubusercontent.com"
      ClientIdList: [ sts.amazonaws.com ]
      ThumbprintList: [ 6938fd4d98bab03faadb97b34396831e3780aea1 ]
```

## 作成するリポジトリ (3) - `prepare` - (3)
GitHub ActionsでOIDCを使ったAssume Roleを行うためのIAM Role。  
条件で使えるリポジトリを制限している。
ここを楽に書くためにGitHubのOrganizationを作成した。
```yaml
  RoleGitHubActions:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !Ref OidcProviderGitHub
            Condition:
              StringLike:
                token.actions.githubusercontent.com:sub: repo:luciferous-library/*
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
```

## 作成するリポジトリ (3) - `prepare` - (4)
LambdaなどのArtifactを置くためのS3 Bucket。  
いつまでも残しておく必要はないので3日で削除する。
```yaml
  BucketLambdaArtifact:
    Type: AWS::S3::Bucket
    Properties:
      LifecycleConfiguration:
        Rules:
          - ExpirationInDays: 3
            Status: Enabled
```

## 作成するリポジトリ (3) - `prepare` - (5)
作成したIAM Role(のARN)をOrganizationのSecretsに登録して、  
CDを行いたいリポジトリでGitHub Actionsにて次のように書けばAssume Roleできる。
```
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-22.04
    steps:
      - uses: aws-actions/setup-sam@v2
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.ARN_IAM_ROLE }}
          aws-region: ap-northeast-1
```

## 作成するリポジトリ (4) - `base` - 
- Lambda Layerなどを作成する
  - Lambda関数と同じリポジトリで作成すると、毎回作成されたりして面倒なので別のリポジトリで作成する
- LambdaをContainer Imageで動かすときは、先に依存ライブラリをインストールしたImageを作成しておく

## 作成するリポジトリ (5) - `secrets` -
- 公開できないSecretsを扱うリポジトリ
  - そのため、このリポジトリはPrivateリポジトリとする必要がある
- SSM ParameterのSecure Stringを主に扱うので、リソース管理はTerraformで行う
  - KMSで暗号化を行うSecure StringはCloudFormationで作成できない

## 作成するリポジトリ (6) - `cloud` - 
- Lambdaの実装とかアプリケーションで必要となるリソースの管理をする
- Lambdaのコードを書く際のテストでAWSのエミュレートをする際にはlocalstackを使用することが多い
  - localstackを動かすときにdocker-composeを使用している
- それなりに規模が大きいものを作る際には、リポジトリを分けるか、Nested Stackを使ってyamlのサイズを小さくする

## 作成するリポジトリ (7) - `web` -
- Webフロントが必要なら、ここにコードを置く
- Amplify ConsoleとかNetlifyとか、S3 + CloudFrontにデプロイを行う
  - Netlifyにデプロイすることが自分は多い

## その他Tips
1. CloudFormationのスタック間の値の参照
   - スタック間の参照ではSSM Parameterを使用
     - Stringの場合には、CloudFormationのParameterとしてしようができる
     - SecureStringの場合にはLambda関数の中で取得するようにする- CloudFormationのスタック間の値の参照
  - スタック間の参照ではSSM Parameterを使用
    - Stringの場合には、CloudFormationのParameterとしてしようができる
    - SecureStringの場合にはLambda関数の中で取得するようにする      

話すこと

  • 自分がサーバーレスアプリケーションを作成する際に、どういった準備などをしているかをまとめてみた
  • AWSのアーキテクチャをどうするとか、そういうことは今回話さない
  • Lambda関数の実装部分も話さない

index

  1. 自己紹介
  2. 使用するもの
  3. 大まかな流れ
  4. AWSアカウントを作成したらすること
  5. 作成するリポジトリ
  6. その他Tips

自己紹介

  • 夏目 祐樹 (ナツメ ユウタ)
  • クラスメソッド株式会社
    • CX事業本部 Delivery部
    • 自称 サーバーレス エンジニア
  • 好きなAWSサービス
    • Lambda, DynamoDB, SQS
  • 最近やってるゲーム
    • FF14 (万魔殿パンデモニウム零式: 煉獄編4層を先週クリア)
    • 空の軌跡 FC Evolution (ハードで6時間かけて序章終わらず)
    • 黎の軌跡II (金策とかやってたら、1章序盤)

使用するもの (1)

  • AWS Organiztion
    • アプリケーション用のアカウントを作成するのに使う
      • 支払いをまとめることが目的
  • github.com
    • コードのホスティング
    • Organization (フリープラン)
    • GitHub Actions (CI/CD)

使用するもの (2)

  • Serverless Application Model (CloudFormation)
    • 原則としてAWSの管理はこれ
    • デプロイ等はsam-cliを使う
  • make
    • タスクランナーとして使う
  • Terraform (optional)
    • SSM ParameterのSecureStringなどを定義するのに使う
      • CloudFormationではSecureStringを作成できない
    • Terraform Cloudをバックエンドとして使う

大まかな流れ

  1. AWS Organiztionで新しいアカウントを作る
    • 作成したら、普段アクセスするためのIAM Roleを作成する
  2. GitHubでOrganizationを作成する
    • 作成しなくてもいいけど、後々の管理を楽にするため
  3. 各種リポジトリを作成しつつ、実装する

AWSのアカウントを作成したらすること

  • 普段使い用のIAM Roleを作成する
    • 基本的にSwitch Roleを使用して複数のAWSアカウントを扱っているため
    • AdministratorAccess
  • LambdaなどのQuotaを確認する
    • 新規作成したアカウントではQuotaがデフォルト値よりも小さいことがあるので確認が必要

作成するリポジトリ (1)

  1. prepare
    • CI/CDのために必要なリソースの作成をする
    • このリポジトリだけは手動でデプロイする
  2. base (optional)
    • Lambda LayerやDocker Imageを作成する
  3. secrets (optional)
    • 各種トークンなどSecretをSSM Parameterに保存する
    • Terraformで管理する

作成するリポジトリ (2)

  1. cloud
    • アプリケーションに必要なLambdaやその他リソースを作成する
  2. web (optional)
    • Webアプリのコードを置く

作成するリポジトリ (3) - prepare - (1)

  • CI/CDに使うものを作成する
    • GitHub ActionsでAWSにアクセスするためのもの
      • AWS::IAM::OIDCProvider
      • AWS::IAM::Role
    • LambdaのArtifactなどを置くためのS3 Bucket

作成するリポジトリ (3) - prepare - (2)

GitHub ActionsでOIDCを使ったAssume Roleを行うためのProvider。
誰が使おうとここ(のProperties)は同じ。
誰が使おうとここ(のProperties)は同じ。

Resource:
  OidcProviderGitHub:
    Type: AWS::IAM::OIDCProvider
    Properties:
      Url: "https://token.actions.githubusercontent.com"
      ClientIdList: [ sts.amazonaws.com ]
      ThumbprintList: [ 6938fd4d98bab03faadb97b34396831e3780aea1 ]

作成するリポジトリ (3) - prepare - (3)

GitHub ActionsでOIDCを使ったAssume Roleを行うためのIAM Role。
条件で使えるリポジトリを制限している。
ここを楽に書くためにGitHubのOrganizationを作成した。

  RoleGitHubActions:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !Ref OidcProviderGitHub
            Condition:
              StringLike:
                token.actions.githubusercontent.com:sub: repo:luciferous-library/*
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess

作成するリポジトリ (3) - prepare - (4)

LambdaなどのArtifactを置くためのS3 Bucket。  
いつまでも残しておく必要はないので3日で削除する。

  BucketLambdaArtifact:
    Type: AWS::S3::Bucket
    Properties:
      LifecycleConfiguration:
        Rules:
          - ExpirationInDays: 3
            Status: Enabled

作成するリポジトリ (3) - prepare - (5)

作成したIAM Role(のARN)をOrganizationのSecretsに登録して、
CDを行いたいリポジトリでGitHub Actionsにて次のように書けばAssume Roleできる。

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-22.04
    steps:
      - uses: aws-actions/setup-sam@v2
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.ARN_IAM_ROLE }}
          aws-region: ap-northeast-1

作成するリポジトリ (4) - base -

  • Lambda Layerなどを作成する
    • Lambda関数と同じリポジトリで作成すると、毎回作成されたりして面倒なので別のリポジトリで作成する
  • LambdaをContainer Imageで動かすときは、先に依存ライブラリをインストールしたImageを作成しておく

作成するリポジトリ (5) - secrets -

  • 公開できないSecretsを扱うリポジトリ
    • そのため、このリポジトリはPrivateリポジトリとする必要がある
  • SSM ParameterのSecure Stringを主に扱うので、リソース管理はTerraformで行う
    • KMSで暗号化を行うSecure StringはCloudFormationで作成できない

作成するリポジトリ (6) - cloud -

  • Lambdaの実装とかアプリケーションで必要となるリソースの管理をする
  • Lambdaのコードを書く際のテストでAWSのエミュレートをする際にはlocalstackを使用することが多い
    • localstackを動かすときにdocker-composeを使用している
  • それなりに規模が大きいものを作る際には、リポジトリを分けるか、Nested Stackを使ってyamlのサイズを小さくする

作成するリポジトリ (7) - web -

  • Webフロントが必要なら、ここにコードを置く
  • Amplify ConsoleとかNetlifyとか、S3 + CloudFrontにデプロイを行う
    • Netlifyにデプロイすることが自分は多い

その他Tips

  • CloudFormationのスタック間の値の参照
    • スタック間の参照ではSSM Parameterを使用
      • Stringの場合には、CloudFormationのParameterとしてしようができる
      • SecureStringの場合にはLambda関数の中で取得するようにする