はじめに
我々tdiはお客様社内の業務システムを開発することがほとんどです。
AWSでサーバーレスな構成を組む時に、フロントエンドをS3とCloudFrontで配信し、バックエンドをAPI Gateway経由のLambdaで、データベースはDynamoDBで・・・というのはよくある構成ですね。
しかし、社内の業務システムとなると、
- インターネット経由でシステムにアクセスしたくない
 - Lambdaのローカル開発に慣れていない
 - データベースはやっぱりRDBMSで構成したい
 
などといった様々な外的要因も無視できません。
そこで今回は、Reactで動いているフロントエンドとSpring Bootで動いているバックエンドを1つのALBから振り分けるようなAWS Fargateの構成をCDKで構築して動かしていきたいと思います。
分量が非常に多くなってしまうので、何回かに分けて連載していく予定です。
最後までお付き合いください。
構成の概要
最終的に動かしていく構成は以下の通りです。

フロントエンド用とバックエンド用のFargateサービスを分け、パスベースルーティングで1つのALBから振り分けます。
今回は「インターネット経由でシステムにアクセスしたくない」という要件は外しましたが、もしその要件を入れる場合はALBをプライベートサブネットで構成するようにしてください。
また、認証にはCognitoを使用しGoogleとフェデレーションします。
そして、Cognitoで認証されたトークンを持っているユーザのみが、バックエンドのAPIを使用できるように認可制御も実装します。
これらの構成の開発手順とCDKでの構築手順をお届けしていきます!
Google認証のためのCognitoをCDKで構築する
第1回となる今回はGoogleとフェデレーションするCognitoをCDKで構築していきます。
前提として、
- 開発環境はWindows
 - AWS CLIのインストール
 - Node.jsのインストール
 - CDKのインストール
 - CDKのデプロイ権限を持ったAWSのプロファイル設定
 - VSCodeのインストール
 - Google認証のためのGoogle Cloud側の設定(OAuthクライアント、同意画面)
 
は完了していることを想定しています。
早速、CDKプロジェクトを作成していきましょう。
適当なフォルダで以下のコマンドを実行して、プロジェクトを作成します。
| 
					 1 2 3  | 
						mkdir -p miso-cdk\miso-auth cd miso-cdk\miso-auth cdk init --language typescript  | 
					
構築する環境ごとに設定を切り分けたいため、dotenvをインストールします。
| 
					 1  | 
						npm install dotenv  | 
					
.envから設定を読み込みようにmiso-auth.tsを編集します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { MisoAuthStack } from '../lib/miso-auth-stack'; import * as dotenv from 'dotenv'; dotenv.config({   path: `.env.${process.env.NODE_ENV}` }); const app = new cdk.App(); new MisoAuthStack(app, 'MisoAuthStack', { });  | 
					
とりあえず開発環境ということで、.env.devファイルを作成します。
ステージング環境なら.env.stg、本番環境なら.env.prdのように作成してください。
| 
					 1 2  | 
						GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret  | 
					
your-google-client-idおよびyour-google-client-secretの値は、Google Cloud側で設定したOAuthクライアントのクライアントIDとクライアントシークレットの値を設定してください。
また、.envがGitリポジトリに保存されないように忘れずに.gitignoreに追加しておきましょう。
| 
					 1 2 3 4 5 6 7 8 9  | 
						*.js !jest.config.js *.d.ts node_modules # CDK asset staging directory .cdk.staging cdk.out .env.*  | 
					
メインとなるCognitoを設定するCDKコードをmiso-auth-stack.tsに記述します。
| 
					 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83  | 
						import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as cognito from 'aws-cdk-lib/aws-cognito'; export class MisoAuthStack extends cdk.Stack {   constructor(scope: Construct, id: string, props?: cdk.StackProps) {     super(scope, id, props);     // 環境変数から情報を取得     const googleClientId = process.env.GOOGLE_CLIENT_ID ?? (() => { throw new Error('GOOGLE_CLIENT_IDが取得できませんでした'); })();     const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET ?? (() => { throw new Error('GOOGLE_CLIENT_SECRETが取得できませんでした'); })();     const callbackUrls = process.env.CALLBACK_URLS?.split(',') ?? (() => { throw new Error('CALLBACK_URLSが取得できませんでした'); })();     const logoutUrls = process.env.LOGOUT_URLS?.split(',') ?? (() => { throw new Error('LOGOUT_URLSが取得できませんでした'); })();     // Cognito User Poolの作成     const userPool = new cognito.UserPool(this, 'CognitoUserPool', {       userPoolName: `miso-${process.env.NODE_ENV}`,       selfSignUpEnabled: true,       signInAliases: {         email: true,       },       autoVerify: { email: true },     });     // Cognito User Poolアプリクライアントの作成     const userPoolClient = new cognito.UserPoolClient(this, 'CognitoAppClient', {       userPool,       authFlows: {         userPassword: true,         userSrp: true,       },       oAuth: {         flows: {           authorizationCodeGrant: true,         },         scopes: [           cognito.OAuthScope.OPENID,           cognito.OAuthScope.EMAIL,           cognito.OAuthScope.PROFILE,           cognito.OAuthScope.COGNITO_ADMIN,         ],         callbackUrls: callbackUrls,         logoutUrls: logoutUrls,       },       supportedIdentityProviders: [         cognito.UserPoolClientIdentityProvider.GOOGLE,       ]     });     // Googleをフェデレーションに設定     const googleProvider = new cognito.UserPoolIdentityProviderGoogle(this, 'Google', {       clientId: googleClientId,       clientSecretValue: cdk.SecretValue.unsafePlainText(googleClientSecret),       userPool,       attributeMapping: {         email: cognito.ProviderAttribute.GOOGLE_EMAIL,         fullname: cognito.ProviderAttribute.GOOGLE_NAME,         profilePicture: cognito.ProviderAttribute.GOOGLE_PICTURE,         givenName: cognito.ProviderAttribute.GOOGLE_GIVEN_NAME,       },       scopes: ['profile', 'email', 'openid'],     });     // AWSが管理するドメインの設定     const cognitoDomain = userPool.addDomain('CognitoDomain', {       cognitoDomain: {         domainPrefix: `miso-${process.env.NODE_ENV}`,       },     });     // User Pool ClientにGoogleプロバイダーを関連付ける     userPoolClient.node.addDependency(googleProvider);     // CDK出力にUserPoolとAppClientのIDを追加     new cdk.CfnOutput(this, 'UserPoolId', {       value: userPool.userPoolId,     });     new cdk.CfnOutput(this, 'UserPoolClientId', {       value: userPoolClient.userPoolClientId,     });   } }  | 
					
コードが完成したので、あとはデプロイするだけ!NODE_ENVをセットするのを忘れずに。
| 
					 1 2 3  | 
						set NODE_ENV=dev cdk bootstrap cdk deploy  | 
					
デプロイが完了すると、以下のようなメッセージ表示され、UserPoolIdとUserPoolClientIdが表示されているのが分かります。
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						 ✅  MisoAuthStack ✨  Deployment time: 18.35s Outputs: MisoAuthStack.UserPoolClientId = abcdefghijklmnop0123456789 MisoAuthStack.UserPoolId = ap-northeast-1_XXXXXXXXX Stack ARN: arn:aws:cloudformation:ap-northeast-1:nnnnnnnnnnnn:stack/MisoAuthStack/00000000-0000-0000-0000-000000000000 ✨  Total time: 32.85s  | 
					
これでGoogle認証を行うCognitoをCDKで構築することができました。
次回は、構築したCognitoで認証するReactのアプリケーションを作成していこうと思います。
それでは、また次回に👋
シリーズ記事
- 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 デジタルイノベーション技術部
 - 
昔も今も新しいものが大好き!
インフラからアプリまで縦横無尽にトータルサポートや新技術の探求を行っています。
週末はときどきキャンプ場に出没します。 
			



