--- Title: 自分のサーバーレスアプリケーションの作り方 Author: sinofseven Web: 'https://mimemo.io/m/2ZJDal8aQL4PKMR' --- ## 話すこと - 自分がサーバーレスアプリケーションを作成する際に、どういった準備などをしているかをまとめてみた - 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 - CloudFormationのスタック間の値の参照 - スタック間の参照ではSSM Parameterを使用 - Stringの場合には、CloudFormationのParameterとしてしようができる - SecureStringの場合にはLambda関数の中で取得するようにする