Upgrade to Pro — share decks privately, control downloads, hide ads and more …

虎の穴ラボ Tech Talk_CDKでFargate環境構築

虎の穴ラボ Tech Talk_CDKでFargate環境構築

虎の穴ラボ Tech Talk #1 〜社内技術LT〜
https://yumenosora.connpass.com/event/328090/

上記のイベントで発表させていただいた内容です

虎の穴ラボ株式会社

September 19, 2024
Tweet

More Decks by 虎の穴ラボ株式会社

Transcript

  1. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. T

    O R A N O A N A L a b CDKでFargate環境構築 虎の穴ラボ はっとり 1
  2. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 自己紹介

    2 本業: ねこ様の従者 副業: 虎の穴ラボのエンジニア 服部 和哉(はっとり かずや) 2020年8月入社 Architect & CSIRTチーム 技術 フロントエンドからインフラまで何でもやりま す。
  3. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. ブログ

    今回の内容はブログでも紹介しています。 本番で使える Fargate環境構築を CDKでやってみる https://toranoana-lab.hatenablog.com/entry/2024/08/15/130000 3
  4. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 発表内容

    最近リリースした新しいアプリケーションで AWS CDKを利用したので整理の意味もあり、 一般的に使えそうな Fargate環境構築を作成するための コードを公開させていただきました。 4
  5. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. アジェンダ

    1. IaCとAWS CDKの概要 2. Fargate環境の構築概要 3. CDKを使ったリソース作成手順 4. 利用したソースコード解説 5. まとめ 5
  6. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. IaCとAWS

    CDKの概要 IaCの重要性 従来の手動設定と比べ、 IaCは再現性と拡張性を確保する上で非 常に有効です。 コードとしてインフラを定義することで、環境間の一貫性を保ちつつ、 チームメンバー全員が簡単にインフラを構築・管理できるようになり ます。 7
  7. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. IaCとAWS

    CDKの概要 AWS CDK(Cloud Development Kit)とは • AWS CDKは、AWSのインフラをコードで 定義し、作成するためのツールです。 • 高レベルの抽象化を提供し、複雑な設定を シンプルなコードにまとめることができます。 8
  8. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. IaCとAWS

    CDKの概要 AWS CDKの選定理由 • CDKは、IAMやセキュリティグループなど関連するリソー スも自動で作成してくれるため、非常に便利。 • CDKでサポートされている言語の中から静的型付けがあ り、社内でも利用実績が多い TypeScriptを選択。 9
  9. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. Fargate環境の構築概要

    Fargateについて • AWS Fargateは、サーバーレスでコンテナを実行で きるサービスです。 • サーバー管理の負担を軽減し、スケーラブルな コンテナ運用ができます。 11
  10. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. CDKを使ったリソース作成手順

    今回使うソースコード ※先程のブログ内にもリンクがあります。 https://github.com/toranoana/cdk-sample-fargate-app 16
  11. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. CDKを使ったリソース作成手順

    ※要AWS CLIのセットアップ 先程のソースを使うと 以下の4コマンドで環境が作れます。 17 $ npm run cdk -- bootstrap $ bin/deploy.sh $ bin/build_and_push.sh $ bin/deploy.sh # 2回目
  12. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. CDKを使ったリソース作成手順

    コマンド解説 18 # そのアカウントでAWS CDKを初めて使う場合に必要 $ npm run cdk -- bootstrap # アプリケーションのイメージと ECSサービスを除いて各リソース構築 $ bin/deploy.sh # アプリケーションのイメージビルドと ECRへpush $ bin/build_and_push.sh # ECRへアプリケーションイメージがあれば ECSサービス作成 $ bin/deploy.sh ※スクリプトの詳細は後ほど
  13. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. CDKを使ったリソース作成手順

    AWS Certificate Manager(ACM)のARNを.envに設定した状態で 構築すると TLSにも対応できます。 ※ACMへの証明書登録と DNSレコード登録は別途対応が必要 19 # .envの内容 # HTTPSを有効にする場合は AWS Certificate Manager に登録してある証明書のARNを指定します。 ACM_ARN=arn:aws:acm:ap-northeast-1:XXXXXXXXXXXX:certificate/xxxxxxxx-xxxx-xxxx-xxxx- xxxxxxxxxxxx
  14. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. CDKを使ったリソース作成手順

    出来上がったアプリケーションにアクセスすると 20 トップページの表示 $ curl (ロードバランサーのURL)/api/samples | jq . [ { "id": 1, "name": "とらのあな", "value": "同人誌販売" }, { "id": 2, "name": "とらのあなラボ", "value": "開発" } ]
  15. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    今回使うソースコード (再) https://github.com/toranoana/cdk-sample-fargate-app 22
  16. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    ディレクトリ構成は このようになります 23 ├── apps │ ├── api │ └── page ├── bin │ ├── build_and_push.sh │ ├── deploy.sh │ └── sample-fargate-app.ts ├── cdk.json ├── lib │ ├── constructs │ │ ├── elastic-container-service.ts │ │ ├── load-balancer.ts │ │ ├── relational-database-service.ts │ │ ├── security-groups.ts │ │ ├── vpc-endpoints.ts │ │ └── vpc-subnets.ts │ ├── sample-fargate-app-stack.ts │ └── settings.ts ├── package.json └── tsconfig.json
  17. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    appsディレクトリ apiとpageの2つのアプリケーションを配置しています。 ※ChatGPTに作成してもらったものに少し手を入れた簡単なアプリケー ションです。 アプリケーションの一部抜粋 24 app.get('/api/samples', async (req, res) => { try { const results = await query('SELECT * FROM samples'); res.json(results); } catch (error) { console.error('Error executing query:', error); res.status(500).send('Internal Server Error'); } }); // Caution: XSS対策されていないので、実際のアプリケーションではこのま ま使用しないでください let tableRows = samples .map((sample) => { return `<tr>${Object.values(sample) .map((value) => `<td>${value}</td>`) .join('')}</tr>`; }) .join(''); let html = ` <html> <head> <title>Samples Table</title> </head> <body> <h1>Samples</h1> <table border="1"> <tr>${Object.keys(samples[0]) .map((key) => `<th>${key}</th>`) .join('')}</tr> ${tableRows} </table> </body> </html> `; res.send(html);
  18. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    binディレクトリ リソース反映時に利用するシェルスクリプトを格納していま す 25
  19. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    binディレクトリ bin/deploy.sh AWS CLIでコンテナリポジトリの最新 (latest)の イメージを取得して環境変数に設定してから cdk deployコマンドを実行する。 ※コンテナリポジトリがないorイメージが存在しない場合は環境 変数は設定しない。 26 #!/bin/bash # (中略) aws ecr describe-repositories \ --repository-names $API_APP_REPOSITORY_NAME \ > /dev/null 2>&1 if [ $? -eq 0 ]; then export API_APP_CONTAINER_TAG=$(aws ecr describe-images \ --repository-name $API_APP_REPOSITORY_NAME \ --query 'imageDetails[?imageTags[?contains(@, `latest`)]].imageDigest' \ --output text) fi aws ecr describe-repositories \ --repository-names $PAGE_APP_REPOSITORY_NAME \ > /dev/null 2>&1 if [ $? -eq 0 ]; then export PAGE_APP_CONTAINER_TAG=$(aws ecr describe-images \ --repository-name $PAGE_APP_REPOSITORY_NAME \ --query 'imageDetails[?imageTags[?contains(@, `latest`)]].imageDigest' \ --output text) fi npm run cdk -- deploy
  20. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    binディレクトリ bin/build_and_push.sh appsディレクトリの中身をビルドし、コンテナリポジト リにpushします。 27 #!/bin/bash # (中略) ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) REGION=ap-northeast-1 aws ecr get-login-password | \ docker login --username AWS --password-stdin \ "$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com" API_APP_REPOSITORY_URI=$(aws ecr describe-repositories \ --repository-names $API_APP_REPOSITORY_NAME \ --query "repositories[0].repositoryUri" \ --output text 2>/dev/null) # (中略) docker build \ --build-arg DATABASE_SSL_CA_URL=$DATABASE_SSL_CA_URL \ --target prod \ -t $API_APP_REPOSITORY_URI:latest apps/api docker build \ -t $PAGE_APP_REPOSITORY_URI:latest apps/page docker push $API_APP_REPOSITORY_URI:latest docker push $PAGE_APP_REPOSITORY_URI:latest
  21. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    libディレクトリ AWS CDKでリソースを作るための TypeScriptソースを 配置しています。 内容が多いので一部だけ抜粋します。 28
  22. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    libディレクトリ lib/constructs/load-balancer.ts ロードバランサー作成処理の一部です。 ACM_ARNがあるかないかでプロトコル (HTTPS/HTTP)を制御します。 29 const appListener = alb.addListener( ACM_ARN ? 'HttpsListener' : 'HttpListener', { port: ACM_ARN ? 443 : 80, protocol: ACM_ARN ? elbv2.ApplicationProtocol.HTTPS : elbv2.ApplicationProtocol.HTTP, certificates: ACM_ARN ? [elbv2.ListenerCertificate.fromArn(ACM_ARN)] : undefined, defaultAction: elbv2.ListenerAction.fixedResponse(404, { contentType: 'text/plain', messageBody: 'Not Found', }), }, );
  23. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 利用したソースコード解説

    libディレクトリ lib/constructs/elastic-container-service.ts ECSサービス作成処理の一部です。 API_APP_CONTAINER_TAGがあればECSサービスを作成 します。 今回はコンテナレジストリも CDKで作成しているため、 初回コマンド実行時点ではコンテ ナイメージがどこにも存在しません。 bin/deploy.shの1回目実行時は ECSサービス以外をすべて作り、コンテナイメージ の用意ができた 2回目の実行で ECSサービスを作るようにしています。 30 if (apiRepo && API_APP_CONTAINER_TAG) { // (タスク定義とECSサービス作成処理) }
  24. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. まとめ

    • AWS CDKを利用することで再現性のある環境構築 ができます。 • 分岐処理が簡単に書けるので環境や状況に応じて作 成するリソースの調整がしやすくなります。 • 複雑なIAMの設定を自動でやってくれるので便利 32