diff --git a/README.md b/README.md index 2cb38888..b7d58ded 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ Sync run history の Status / Summary に Completed が表示されれば完了 - 開発 - [ローカル開発環境構築手順](/docs/DEVELOPMENT.md) - [ユースケースの追加方法 (ブログ: Amazon Bedrock で Interpreter を開発!)](https://aws.amazon.com/jp/builders-flash/202311/bedrock-interpreter/#04) + - [リソースの削除方法](/docs/DESTROY.md) ## Security diff --git a/docs/DESTROY.md b/docs/DESTROY.md new file mode 100644 index 00000000..354b2127 --- /dev/null +++ b/docs/DESTROY.md @@ -0,0 +1,23 @@ +# リソースの削除方法 + +以下のコマンドを実行してください。**Cognito UserPool, DynamoDB Table など全てのデータが削除されます。** + +```bash +npm run cdk:destroy +``` + +## エラーになった場合 + +以下のようなエラーが発生することがあります。 + +> **The bucket you tried to delete is not empty. You must delete all versions in the bucket.** + +S3 Bucket は削除する時に中身を空にする必要があります。AWS CDK のオプションで `autoDeleteObjects: true` を指定することで、削除の前に中身を自動で空にできるのですが、空にしてから実際に削除するまでの間に新たなファイルが追加されることで、上記エラーが発生します。 + +このエラーが発生した場合は、以下の手順に従って手動で Stack を削除してください。 + +1. [AWS CloudFormation](https://console.aws.amazon.com/cloudformation/home) を開き、GenerativeAiUseCasesStack を選択。 +1. Delete を押下。この際に削除に失敗した S3 Bucket の削除をスキップするか聞かれるため、チェックを入れて削除を実行。 +1. 削除をスキップした S3 Bucket を除いたリソースの削除が完了する。 +1. [Amazon S3](https://s3.console.aws.amazon.com/s3/home) を開き、スキップした S3 Bucket を探す。("generative" 等で検索してください。) +1. Empty (Bucket を空にする) => Delete (Bucket を削除する) を実行 diff --git a/package.json b/package.json index a46fa657..4c2f94da 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "web:build": "npm -w packages/web run build", "web:lint": "npm -w packages/web run lint", "cdk:deploy": "npm -w packages/cdk run cdk deploy --", + "cdk:destroy": "npm -w packages/cdk run cdk destroy", "cdk:lint": "npm -w packages/cdk run lint" }, "devDependencies": { @@ -22,4 +23,4 @@ "workspaces": [ "packages/*" ] -} \ No newline at end of file +} diff --git a/packages/cdk/bin/generative-ai-use-cases.ts b/packages/cdk/bin/generative-ai-use-cases.ts index 5f86f444..a9f0aa2f 100644 --- a/packages/cdk/bin/generative-ai-use-cases.ts +++ b/packages/cdk/bin/generative-ai-use-cases.ts @@ -1,8 +1,20 @@ #!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; +import { IConstruct } from 'constructs'; import { GenerativeAiUseCasesStack } from '../lib/generative-ai-use-cases-stack'; +class DeletionPolicySetter implements cdk.IAspect { + constructor(private readonly policy: cdk.RemovalPolicy) {} + + visit(node: IConstruct): void { + if (node instanceof cdk.CfnResource) { + node.applyRemovalPolicy(this.policy); + } + } +} + const app = new cdk.App(); +const stack = new GenerativeAiUseCasesStack(app, 'GenerativeAiUseCasesStack'); -new GenerativeAiUseCasesStack(app, 'GenerativeAiUseCasesStack'); +cdk.Aspects.of(stack).add(new DeletionPolicySetter(cdk.RemovalPolicy.DESTROY)); diff --git a/packages/cdk/lib/construct/web.ts b/packages/cdk/lib/construct/web.ts index 06c1af5c..420306a1 100644 --- a/packages/cdk/lib/construct/web.ts +++ b/packages/cdk/lib/construct/web.ts @@ -21,19 +21,23 @@ export class Web extends Construct { constructor(scope: Construct, id: string, props: WebProps) { super(scope, id); + const commonBucketProps: s3.BucketProps = { + blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, + encryption: s3.BucketEncryption.S3_MANAGED, + autoDeleteObjects: true, + removalPolicy: RemovalPolicy.DESTROY, + objectOwnership: s3.ObjectOwnership.OBJECT_WRITER, + enforceSSL: true, + }; + const { cloudFrontWebDistribution, s3BucketInterface } = new CloudFrontToS3( this, 'Web', { insertHttpSecurityHeaders: false, - bucketProps: { - blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, - encryption: s3.BucketEncryption.S3_MANAGED, - autoDeleteObjects: true, - removalPolicy: RemovalPolicy.DESTROY, - objectOwnership: s3.ObjectOwnership.OBJECT_WRITER, - enforceSSL: true, - }, + loggingBucketProps: commonBucketProps, + bucketProps: commonBucketProps, + cloudFrontLoggingBucketProps: commonBucketProps, cloudFrontDistributionProps: { errorResponses: [ {