View this page in English サーバーレスのサンプルアプリケーションを構築する場合はこちら
AWS 上にサンプルアプリケーションやバッチシステムを動かす環境を構築する CDK のコードです。
CDK を利用するため、コマンドを実行する端末で AWS の設定が必要になります。
$ aws configure --profile {プロファイル名}
と実行し、表示されるプロンプトに応じて、必要な情報を入力してください。
IAM ユーザ作成時に表示される、アクセスキーとシークレットキー、デフォルトのリージョンが確認されます。 詳しくはaws configure を使用したクイック設定 - プロファイルをご参照ください。
本テンプレートは、タスクランナーのgulpを利用してデプロイを行います。
gulp から参照される変数がstages.js
で定義されているため、各自の環境に合わせて変更します。
default: {
appName,
awsProfile: 'myProfile',
alias: 'default',
deployEnv: 'dev',
notifyEmail: '[email protected]',
enabledPrivateLink: false,
windowsBastion: true,
linuxBastion: true,
domainName: 'templateapp.local',
},
alias: {
appName: '', // アプリの名前を入力します。 例: demoapp, など
awsProfile: '', // 1で設定したProfile名を入力します。
alias: '', // 個々人で環境面が被るのを回避するため、ユーザ名などの識別子を入力してください。 例: ysuzuki, など
deployEnv: '' // デプロイする環境の面を記載します。例: dev, stage, prod, など
notifyEmail: '', // ジョブが失敗した際の通知先メールアドレス
enabledPrivateLink: false, // PrivateLinkを利用するかどうか。trueは利用し、falseは利用しない
windowsBastion: true, // WindowsのBastionインスタンスを利用する場合はtrue、利用しない場合はfalse
linuxBastion: true, // Amazon LinuxのBastionインスタンスを利用する場合はtrue、利用しない場合はfalse
domainName: 'templateapp.local', // Private Hosted Zoneに登録されるドメイン名
}
HTTPS 通信を実装するために、今回は自己署名付き証明書を用います。
infra
ディレクトリで次のコマンドを実行し、Amazon Certificate Manager に証明書をインポートしてください。
また、以下のコマンド実行前に、OpenSSL
のインストールを実施してください。
$ npm install
$ npm run create-certificate -- --{alias}
infra
ディレクトリで以下のコマンドを実行してください。
自動的に CDK が実行され、AWS の各リソースが生成されます。
$ npm run deploy -- --{alias}
デプロイ後、ターミナル上に以下に示すようなコマンドが出力されますので、コピーして実行してください。 生成された EC2 インスタンス 用の Keypair がそれぞれ取得できます。 コンソール接続する場合や Fleet Manager から RDP 接続する際には、Keypair の取得を行ってください。(コマンド実行時には Profile の指定をお願いします)
// regionがap-northeast-1のWindowsインスタンスの場合
$ {alias}{stage}{appName}Webapp.WindowsGetSSHKeyForWindowsInstanceCommand = aws ssm get-parameter --name /ec2/keypair/key-XXXXXXXXXXXXXXXXX --region ap-northeast-1 --with-decryption --query Parameter.Value --output text
// regionがap-northeast-1のAmazonLinuxインスタンスの場合
$ {alias}{stage}{appName}Webapp.LinuxGetSSHKeyForLinuxInstanceCommand = aws ssm get-parameter --name /ec2/keypair/key-XXXXXXXXXXXXXXXXX --region ap-northeast-1 --with-decryption --query Parameter.Value --output text
NOTE: 初回デプロイ時は、ターミナルの出力が多いため、Keypair を取得するためのコマンドが見えなくなってしまうことがあります。 その場合は、ブラウザから CloudFormation のコンソールを開き、Webapp スタックの出力タブからご確認ください。
また、CDK のデプロイが完了すると、stages.js
に登録したメールアドレス宛に、Amazon SNS よりサブスクリプションの確認メールが届きます。
ジョブが失敗した通知を受けるために、届いたメールの内容に従い、サブスクリプションの Confirmation を実施してください。
また、バッチジョブは平日 21 時に実行される設定になっています。このあと実施する、サンプル Web アプリのデプロイによって登録される初期データは、ジョブがすべて成功する設定になっているため、メールは送信されません。
もし、失敗を確認したい場合は、webapp-java/src/main/resources/data.sql
の 5 つあるtrue
のいずれかをfalse
へ変更した上で、Web アプリのデプロイを行ってください。
CDK のデプロイが完了したことで、AWS CodeCommit に サンプル Web アプリ用のリポジトリが作成されています。
NOTE: リポジトリの URL はデプロイをしたターミナルもしくは、CloudFormation のコンソールに表示されます。 CloudFormation のコンソールを参照する場合は、
baseStack
の出力
タブを参照ください。
以下の手順で、webapp-java
ディレクトリのソースコードをプッシュすることで、サンプル Web アプリがパイプラインからデプロイされます。
$ cd ./webapp-java
$ git init
$ git remote add origin https://git-codecommit.{your region}.amazonaws.com/v1/repos/{your repository name}
$ git add .
$ git commit -m "Initial commit"
$ git push --set-upstream origin main
$ git checkout -b develop
$ git push --set-upstream origin develop
NOTE: CodePipeline のトリガーは develop ブランチを監視しています。そのため、develop ブランチの作成が必要になります。
パイプラインの状況を確認したい場合は、マネジメントコンソールより AWS CodePipeline へアクセスしてください。
Web アプリ向けの CI/CD は BlackBelt で紹介されている構成例(Page 52)を元に実装しています。
ご自身の Web アプリケーションに差し替えたい場合は、CodeCommit にプッシュするソースコードをご自身のものに差し替え、ご自身の環境やアプリケーションに合わせ、Dockerfile を修正してください。
デプロイした Web アプリの動作を確認したい場合、Bastion として構築した Windows が起動している EC2 上でブラウザを起動し、アプリケーションにアクセスします。
Bastion にアクセスする Keypair はデプロイ - 1. CDKで取得したものを利用し、Fleet Manager 経由でアクセスします。 Fleet Manager を利用した RDP 接続の方法は、リモートデスクトップを使用してマネージドノードへ接続するを参照ください。
Bastion への RDP 接続ができたら、ブラウザを起動し、stages.js
のdomainName
で指定したドメインを入力し、アプリケーションにアクセスしてください。
次のような画面が表示されたら成功です。
生成した環境を削除したい場合は、以下のコマンドを実行してください。 ECR など、状況によっては残ってしまうリソースもあるため、手動での削除が必要な場合があります。 ご参考:(ecr): add option to auto delete images upon ECR repository removal #12618 コマンドが失敗した場合は、エラーメッセージや CloudFormation のコンソールで内容をご確認の上、対応ください。
$ npm run destroy -- --{alias}
CDK のコマンドである、diff, list
は、gulp で実装済みのため、これらのコマンドも gulp 経由で実行可能です。
$ npm run diff -- --{alias}
$ npm run list -- --{alias}
ジョブ管理基盤は、「① ワークフローが作成できること」「② 再実行が可能なこと」「③ 失敗時に通知が出せること」といった機能が求められます。 ① のワークフローについては、Step Functions で実現可能ですが、② や ③ は実装が必要になります。 本サンプルでは、この ②、③ の実装例をご提供します。
今回実装したサンプルは、Step Functions のステートマシンが親子関係になっており、親側がメインのワークフロー、子側で ② と ③ を実現しています。 ステートマシンにおけるワークフローの作成方法については、公式のドキュメントをご参照ください。
ここでは、実装している ②、③ について解説します。 以下の図は、親のステートマシンから呼び出される、子のステートマシンを示しています。
子のステートマシンでは、ある一つのジョブスクリプトが実行されますが、以下の流れに沿って実行されます。
- ジョブスクリプトの当日の実行状態を確認する
- ジョブが成功しているか判定する
- 成功していれば、ジョブはスキップされます
- 成功以外であれば、ジョブスクリプトを実行する
- ジョブスクリプトの結果が成功なら、実行状態を"SUCCEEDED"として登録し、このステートマシンを終了する
- ジョブスクリプトの結果が失敗なら、実行状態を"FAILED"として登録する
- 続けて、失敗したことをメールで通知する
- ステートマシンとして失敗したことを設定し、終了する
状態の確認や状態の登録時に、DynamoDB にアクセスし、ジョブの実行状態が、実行日付とジョブの ID をキーとして、参照・登録されます。 このような実行状態の管理を行うことで、② のジョブの再実行を可能にしています。
③ のジョブの失敗通知は、Step Functions が SNS の API を実行することで、失敗したジョブ ID を連携し、購読されているメールアドレスに通知が送信されます。
本プロジェクトの CDK のコードは、cdk-nagを利用して静的解析を実施しています。 提供されているルールに沿った実装ができているか確認することで、致命的なセキュリティリスクを予防します。
例外化しているルールは、ソースコードの下部にまとめて記載しています。 必要に応じて例外化の追加・削除を実施ください。
具体的な使い方については、AWS Cloud Development Kit と cdk-nag でアプリケーションのセキュリティとコンプライアンスを管理する、にて解説していますので、ご参照ください。
Security Hub を有効にした場合、デフォルトで有効になる基準は以下の 2 つです。
- AWS Foundational Security Best Practices (FSBP) standard
- Center for Internet Security (CIS) AWS Foundations Benchmark v1.2.0
これらのチェックが行われると、ベンチマークレポートで重要度が CRITICAL あるいは HIGH のレベルでレポートされる検出項目があります。 これらに対しては、別途対応が必要になります。
- [CIS.1.13] Ensure MFA is enabled for the "root" account
- [CIS.1.14] Ensure hardware MFA is enabled for the "root" account
- [IAM.6] Hardware MFA should be enabled for the root user
- ルートユーザで AWS にログインし、以下のドキュメントに沿って MFA を有効化してください。
- CodeBuild では、Docker イメージをビルドする必要がある場合を除き、特権モードは無効化してください。本テンプレートでは、Docker イメージのビルドを行っているため、有効化していますが、実際に利用される場合は、ご自身の環境に合った設定にご変更ください。
- テンプレートだけの対応であれば、CodePipeline のコンストラクト内の特権モードの設定を
false
に変更してください。 - ご参考:interface BuildEnvironment - privileged
- テンプレートだけの対応であれば、CodePipeline のコンストラクト内の特権モードの設定を
運用管理のため EC2 インスタンスを利用する場合、パッチを当てる方法についてもご検討ください。 Session Manager を経由して手動でパッチを当てることも可能ですが、自動でパッチを当てるには、Patch Manager が有用です。 詳しくは、AWS Systems Manager Patch Managerをご参照ください。
また、パッチ適用といった変更管理における考え方に限らず、AWS では長年培った経験をもとにベストプラクティスをフレームワークとしてまとめた、AWS Well-Architected Frameworkを公開しています。ぜひご参照ください。
本サンプルでは、バッチのコンテナイメージのタグに latest が付与されています。 Web アプリのコンテナイメージに対しては、CodeCommit へのコミットから始まるパイプラインによって、コミットハッシュを利用したバージョンニングを実施します。 バッチでも同様のパイプラインを導入することで、コミットハッシュを利用したバージョニングが可能です。
本サンプルでは、自己署名付き証明書を利用して HTTPS を用いた通信を行なっています。 自己署名付き証明書のため、あくまで検証用としてご利用ください。