CDKでFargateをデプロイする(準備編)
長らく続いた連載もいよいよ終盤に差し掛かってきました。
これまで作ってきた構成をCDKを使ってデプロイしていくのですが、本記事はその準備編となります。
ちなみに、前回の記事はコチラ。
自己署名証明書の作成
CognitoのコールバックURLは、基本的にHTTPSのURLしか指定できず、例外としてlocalhostを含む場合のみHTTPを指定することができます。
ローカル環境で開発しているときはURLがhttp://localhost:3000/だったのでHTTPのままでよかったのですが、今回はHTTPSでなければなりません。
本来はカスタムドメインを作成して、ACMで証明書を作成して、のような形で進めると思いますが、今回はお試しのため自己署名証明書で対応します。
AWSマネジメントコンソールからCloudShellを起動し、以下のようなコマンドを実行して自己署名証明書をACMにインポートしておいてください。
こういうときにCloudShellは便利ですよね!
ちなみにコモンネームは、*.ap-northeast-1.elb.amazonaws.comというワイルドカードを指定して横着していますので、あくまでお試しということでご容赦ください。
1 2 3 4 |
openssl genrsa -out private-key.pem 2048 openssl req -new -key private-key.pem -out csr.pem -subj "/C=JP/ST=Tokyo/L=Shinjuku/O=T.D.I.Co.,Ltd./CN=*.ap-northeast-1.elb.amazonaws.com" openssl x509 -req -days 365 -in csr.pem -signkey private-key.pem -out certificate.pem aws acm import-certificate --certificate fileb://certificate.pem --private-key fileb://private-key.pem |
インポートが成功すると、証明書のARNが表示されますので、控えておいてください。
また、CloudShellは一時的な使用ですので、インポートが終わったら忘れずにCloudShellのアクションから証明書のファイル群をダウンロードしておきましょう。
Dockerfileの作成
今回フロントエンドもバックエンドもFargate上で動かすので、アプリケーションをコンテナ化する必要があります。
各アプリケーションのプロジェクトルートにDockerfileを作成します。
まずはフロントエンドから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# ビルド環境としてNode.js 20を使用します FROM public.ecr.aws/docker/library/node:20 AS build-stage # アプリケーションの作業ディレクトリを作成します WORKDIR /app # package.jsonとpackage-lock.jsonをコピーします COPY package*.json ./ # 依存関係をインストールします RUN npm install # ビルド時に使用する環境変数を設定します ARG VITE_USER_POOL_ID ARG VITE_APP_CLIENT_ID ARG VITE_COGNITO_DOMAIN ENV VITE_USER_POOL_ID=$VITE_USER_POOL_ID ENV VITE_APP_CLIENT_ID=$VITE_APP_CLIENT_ID ENV VITE_COGNITO_DOMAIN=$VITE_COGNITO_DOMAIN # アプリケーションのソースコードをコピーします COPY . . # アプリケーションをビルドします RUN npm run build # 実行環境としてnginxを使用します FROM public.ecr.aws/docker/library/nginx:alpine AS production-stage # ビルドステージからビルド成果物をコピーします COPY --from=build-stage /app/dist /usr/share/nginx/html # nginxの設定ファイルをコピーします COPY nginx.conf /etc/nginx/conf.d/default.conf # ポート80を公開します EXPOSE 80 # nginxをフォアグラウンドで実行します ENTRYPOINT ["nginx", "-g", "daemon off;"] |
ここでポイントが2つあります。
1つ目は、Dockerの元イメージをECR Public Galleryから取得するようにしていることです。
最終的にはDockerイメージのビルドをCodeBuildでやることになるのですが、Docker Hubから元イメージを取得すると、いわゆる「CodeBuildのIPガチャ」に引っかかってしまうため、これを回避するためにECR Public Galleryを使用しています。
2つ目は、環境によって変化する環境変数をビルドの際に使用していることです。
Fargateのタスクが起動するときに環境変数を指定しても、その値は使用されません。
他にいい方法がありましたら、是非教えてください!
また、フロントエンドを配信するのにnginxを使用するため、nginx.confも以下のようにプロジェクトのルートに作成してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } |
試しにdocker buildしてみましょう。
プロジェクトのルート(miso-frontendの下)で以下のコマンドを実行します。
1 |
docker build -t miso-frontend . |
すると、npm run buildのところで以下のようなエラーが出てしまいました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
> [build-stage 6/6] RUN npm run build: 0.555 0.555 > miso-frontend@0.0.0 build 0.555 > tsc -b && vite build 0.555 3.729 src/main.tsx(9,19): error TS2345: Argument of type '{ Auth: { Cognito: { userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }; }; }' is not assignable to parameter of type 'ResourcesConfig | LegacyConfig | AmplifyOutputs'. 3.729 Type '{ Auth: { Cognito: { userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }; }; }' is not assignable to type 'ResourcesConfig'. 3.729 Types of property 'Auth' are incompatible. 3.729 Type '{ Cognito: { userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }; }' is not assignable to type 'AuthConfig | undefined'. 3.729 Type '{ Cognito: { userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }; }' is not assignable to type 'Partial<AuthUserPoolAndIdentityPoolConfig & Partial<Record<never, never>>> & Pick<AuthUserPoolAndIdentityPoolConfig & Partial<...>, "Cognito">'. 3.729 Type '{ Cognito: { userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }; }' is not assignable to type 'Partial<AuthUserPoolAndIdentityPoolConfig & Partial<Record<never, never>>>'. 3.729 Types of property 'Cognito' are incompatible. 3.729 Type '{ userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }' is not assignable to type 'CognitoUserPoolAndIdentityPoolConfig'. 3.729 Type '{ userPoolId: any; userPoolClientId: any; loginWith: { oauth: { domain: any; scopes: string[]; redirectSignIn: string[]; redirectSignOut: string[]; responseType: string; }; }; }' is not assignable to type 'CognitoUserPoolConfig'. 3.729 The types of 'loginWith.oauth.responseType' are incompatible between these types. 3.729 Type 'string' is not assignable to type '"code" | "token"'. |
どうやらTypeScriptの型チェックに引っかかってしまったようです。
JSONで書くやり方もありますが、もともとawsconfig.tsは以下のように環境変数を読み込むようにしているため、そうもいきません。
(注意!)awsconfig.tsのredirectSignInとredirectSignOutの値ですが、CDKでデプロイする時点ではALBのFQDNが確定していないため、リクエストされた元のFQDNをそのまま使用するように変更しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const awsconfig = { Auth: { Cognito: { userPoolId: import.meta.env.VITE_USER_POOL_ID, userPoolClientId: import.meta.env.VITE_APP_CLIENT_ID, loginWith: { oauth: { domain: import.meta.env.VITE_COGNITO_DOMAIN, scopes: ["email", "openid", "profile"], redirectSignIn: [ `${window.location.origin}/` ], redirectSignOut: [ `${window.location.origin}/` ], responseType: "code", }, }, }, }, }; export default awsconfig; |
そのため、main.ts側で以下のようにします。
1 2 |
// Amplify.configure(awsconfig); Amplify.configure(awsconfig as any); |
これで再度docker buildしたところ、成功しました!(もっといいやり方ありそうですが…)
次にバックエンドのDockerfileを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# ベースイメージとしてEclipse TemurinのJava 17およびMavenを使用します FROM public.ecr.aws/docker/library/maven:3.8.6-eclipse-temurin-17 as build # アプリケーションの作業ディレクトリを作成します WORKDIR /app # Mavenの依存キャッシュを活用するために、まずpom.xmlをコピーします COPY pom.xml . # プロジェクトの依存関係を解決します RUN mvn dependency:go-offline # プロジェクトソースをコピーします COPY src ./src # プロジェクトをビルドします RUN mvn clean package -DskipTests # 実行ステージ FROM public.ecr.aws/docker/library/openjdk:17-jdk-slim # アプリケーションの作業ディレクトリを作成します WORKDIR /app # 証明書のコピー COPY certificate.pem /etc/ssl/certs/ # 証明書のインポート RUN keytool -import -trustcacerts -file /etc/ssl/certs/certificate.pem -alias untrustedCert -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt # ビルドステージからJARファイルをコピーします COPY --from=build /app/target/*.jar app.jar # アプリケーションを実行するためのエントリーポイントを指定します ENTRYPOINT ["java", "-jar", "app.jar"] |
ここでのポイントは、証明書のインポートを行っていることです。
リソースサーバがJWT検証URLにアクセスして認可をしますが、ALBが自己署名証明書で動く想定のため、信頼された証明書として登録しておかないと接続できないためです。
ちなみにインポートの際には証明書ストアのデフォルトのパスワードchangeitを使用しています。
自己署名証明書の作成のところでダウンロードしておいたcertificate.pemもプロジェクトのルートに配置しておきましょう。
これで準備が整いました!
次回はついに最終回!!
CDKのコードを作成してデプロイしていきます。
それでは、また次回に👋
シリーズ記事
- React×Spring Bootな構成をAWS Fargateで動かす(1) ~ Cognitoの構築
- React×Spring Bootな構成をAWS Fargateで動かす(2) ~認証付きフロントエンドの作成
- React×Spring Bootな構成をAWS Fargateで動かす(3) ~バックエンドの作成
- React×Spring Bootな構成をAWS Fargateで動かす(4) ~認可機能の追加
- React×Spring Bootな構成をAWS Fargateで動かす(5) ~構成上の問題の解消方法
- React×Spring Bootな構成をAWS Fargateで動かす(6) ~ Fargateのデプロイ(準備編)
- React×Spring Bootな構成をAWS Fargateで動かす(7) ~ Fargateのデプロイ(実装・デプロイ編)
執筆者プロフィール

- tdi デジタルイノベーション技術部
-
昔も今も新しいものが大好き!
インフラからアプリまで縦横無尽にトータルサポートや新技術の探求を行っています。
週末はときどきキャンプ場に出没します。
この執筆者の最新記事
Pick UP!2025.03.18React×Spring Bootな構成をAWS Fargateで動かす(7) ~ Fargateのデプロイ(実装・デプロイ編)
Pick UP!2025.02.27React×Spring Bootな構成をAWS Fargateで動かす(6) ~ Fargateのデプロイ(準備編)
Pick UP!2025.02.19React×Spring Bootな構成をAWS Fargateで動かす(5) ~ 構成上の問題の解消方法
Pick UP!2025.02.07React×Spring Bootな構成をAWS Fargateで動かす(4) ~ 認可機能の追加