はじめに
AWSを用いて個人開発用のバックエンドを構築したのでベストプラクティスを記しておこうと思います。サンプルは以下に。
概要
単純なユーザーデータを扱うDBを構築するものとします。
- 単一取得(GET)
- 全件取得(GET)
- 新規登録(CREATE)
- 更新(UPDATE)
- 削除(DELETE)
また、Gitのpush時に自動でビルドとデプロイを行います。(CI/CD)
使用するサービスやライブラリは以下の通り
- AWS
- APIGateWay
- Lambda
- DynamoDB
- CodePipeLine
- CodeBuild
- TypeScript
- Node.js
- express
- aws-sdk
作業
Node.jsプロジェクトの作成
- 下記コマンドを実行
mkdir <プロジェクト名> cd <プロジェクト名> npm init -y npx tsc --init mkdir src touch src/index.ts touch README.md touch .gitignore
-
tsconfig.json
を以下のように編集tsconfig.json{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] }
-
.gitignore
を以下のように編集./gitignorenode_modules dist
-
src/index.ts
を以下のように編集src/index.tsimport express from "express"; import serverless from "@vendia/serverless-express"; const app = express(); app.use(express.json()); app.get("/", (req, res) => { res.send("Hello"); }); export const handler = serverless({ app });
Gitの初期化
GitHubで新しいリポジトリを作成してください。(Add README.mdは選ばない)
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<ユーザー名>/<プロジェクト名>.git
git push -u origin main
ライブラリの追加
.gitignore
でnode_modules
を設定してないとファイルが多すぎてリモートがパンクするかもなので後から行いました。
npm install --save-dev typescript ts-node @types/node
npm i express @vendia/serverless-express
CodePipelineを作成
- AWSのコンソールからCodePipelineにアクセス
- 右上から新規作成
- カスタムパイプラインの構築を選択
- Step2の必要事項を入力
- Step3でGitHubに連携(アプリ経由を選択し後はデフォルト通りに進む)
- Step4でその他ビルドプロバイダーを選択
- Step5でテストステージはスキップ
- Step6でデプロイステージもスキップ
- 本当はデプロイステージでデプロイすべきだがうまく連携が取れなかったのでbuildステージでデプロイする
- Step7で作成
Lambdaを作成
APIGateWayの作成
- AWSのコンソールから APIGateWayにアクセス
- 右上から新規作成
- "HTTP API"を選択
- APIの設定を行う
- ルートを設定
- 作成
IAMを編集
AWS上での権限を編集します。
-
コンソールからIAMにアクセス
-
左のメニューからロールを選択
-
右の"許可を追加"を選択し"ポシリーをアタッチ"を選択
-
以下のポリシーを選択して追加
- AWSLambda_FullAccess
- AmazonAPIGatewayAdministrator
-
同様にロールから
lambda
が含まれるものを選択し以下を追加- AmazonDynamoDBFullAccess
ビルドワークフローの作成
エディタでの作業に戻ります。
- ワークフローファイルの作成
touch buildspec.yml
- 編集
buildspec.yml
version: 0.2 env: variables: FUNCTION_NAME: "my-api" ALIAS_NAME: "dev" STAGE_NAME: "dev" API_NAME: "my-api" phases: install: commands: - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip -q awscliv2.zip - ./aws/install --install-dir ~/aws-cli --bin-dir ~/bin --update - export PATH=~/bin:$PATH - npm install - npm install -g typescript pre_build: commands: - echo No Pre Build phase build: commands: - echo Build started on `date` - tsc - CurrentVersion=$(aws lambda get-alias --function-name $FUNCTION_NAME --name $ALIAS_NAME --query 'FunctionVersion' --output text) - echo "Zipping deployment package" - mkdir -p deploy-package - cp -r dist/* deploy-package/ - cp -r node_modules deploy-package/ - cd deploy-package - zip -q -r ../lambda.zip . - cd .. - aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://lambda.zip --debug - sleep 10 post_build: commands: - echo Build completed on `date` - ls - aws lambda publish-version --function-name $FUNCTION_NAME --description "update version" - TargetVersion=$(aws lambda list-versions-by-function --function-name $FUNCTION_NAME --query 'Versions[-1].Version' --output text) - echo $CurrentVersion - echo $TargetVersion - LC_ALL=C.UTF-8 aws lambda update-alias --function-name $FUNCTION_NAME --name $ALIAS_NAME --function-version $TargetVersion - | if [ "$CurrentVersion" != "$TargetVersion" ]; then aws lambda delete-function --function-name $FUNCTION_NAME --qualifier $CurrentVersion fi - echo "Deploying API Gateway" - API_ID=$(aws apigatewayv2 get-apis --query "Items[?Name==\`$API_NAME\`].ApiId" --output text) - aws apigatewayv2 create-deployment --api-id $API_ID --stage-name $STAGE_NAME - echo "Deployment completed for HTTP API $API_ID at stage $STAGE_NAME"
完成(仮)
まとめ
今回はプロジェクトを作成して自動でデプロイされるまでを作成しました。次回はレイヤードアーキテクチャで中身を作成していきます。
参考記事