はじめに
みなさん、CDKでインフラ構築する際に共通化などしていますか?
同じようなAWS構成を別プロジェクトで利用することってよくありますよね?
今回は、自作Constructを特定のリポジトリにpushし、別リポジトリからnpm installで利用してデプロイする
を試してみます。
※今回は、別リポジトリからnpm installできることをゴールとするため、細かい説明は省略します
動作環境・使用するツールや言語など
- CDK(TypeScript)
- Gitlab
- npm
カスタムConstructを自作して、Gitlab Packeage Registryにpushしてみる
それでは実際に作りながら、説明していきます。
新規CDKプロジェクト(Construct)の作成
まず以下コマンドで、CDK(TypeScript)のConstructライブラリのひな形を作成します。
cdk init lib --language=typescript
👇以下のファイルが作られます
.git/
.gitignore
.npmignore
jest.config.js
lib/
node_modules/
package.json
package-lock.json
README.md
test/
tsconfig.json
lib/index.tsを開くと以下のようなファイルが出来ていると思います。
// import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export interface CustomBucketProps {
// Define construct properties here
}
export class CustomBucket extends Construct {
constructor(scope: Construct, id: string, props: CustomBucketProps = {}) {
super(scope, id);
// Define construct contents here
// example resource
// const queue = new sqs.Queue(this, 'CdkTest2Queue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
}
}
カスタムConstructの作成
CustomBucketを以下のように修正して、S3バケットを作るコンストラクタを作ります。
import { Construct } from 'constructs';
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
export interface CustomBucketProps {
readonly bucketNamePrefix: string;
}
export class CustomBucket extends Construct {
constructor(scope: Construct, id: string, props: CustomBucketProps) {
super(scope, id);
// Get AWS Account ID
const { accountId } = new cdk.ScopedAws(this);
// Create Bucket
new s3.Bucket(this, `${props.bucketNamePrefix}-Bucket`, {
bucketName: `${props.bucketNamePrefix}-${accountId}`,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
encryption: s3.BucketEncryption.S3_MANAGED,
publicReadAccess: false,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
accessControl: s3.BucketAccessControl.LOG_DELIVERY_WRITE,
enforceSSL: true,
versioned: true,
});
}
}
ビルドして問題ないことを確認します。
npm run build
> custom-bucket@0.1.0 build
> tsc
Gitlab Packeage Registryの準備
Gitlab Packeage Registryを利用することで、npmなどのパッケージをgitlab上で管理することが出来ます。
リポジトリを作成し、Settings
のRepository
をクリックします。
Deploy tokens
を開き、
-
Name
:任意のトークン名 -
Username
:任意のユーザ名 -
Scopes
:read_package_registry
とwrite_package_registry
を入力し、Create deploy token
をクリックすると、トークンが発行されます。
作成した時にしかトークンは確認できないので、必ずどこかに保存するようにしましょう。
Gitlab Packeage Registryにpush
準備が出来たので実際にpushしていきます。
Pacakges and registries
のPackage Registry
をクリックします。
またpushしていないので、一覧には何も表示されないはずです。
package.jsonを以下のように修正します。
-
name
:npm isntallする際のパッケージ名になります -
version
:どのバージョンでpushするか指定します
{
"name": "@nakazato-cdk-assets/my-construct",
"version": "0.1.0",
"description": "this package is original cdk construct",
"main": "lib/index.js",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"dependencies": {
"aws-cdk-lib": "^2.0.0",
"constructs": "^10.0.0"
},
"author": "m.nakazato",
"license": "ISC"
}
.npmrc
ファイルを作成し、以下のように記述します。
@nakazato-cdk-assets:registry=https://${ドメイン名}/api/v4/projects/${プロジェクトID}/packages/npm/
//${ドメイン名}/api/v4/projects/1834/packages/npm/:_authToken="${NPM_TOKEN}"
NPM_TOKEN=${先ほど作成したデプロイトークン} npm publish
Registry一覧を見ると、0.1.0で無事pushされました
Constructをnpm installして、デプロイしてみる
では、最後に先ほどpushしたConstructをインストールして、デプロイしてみましょう!
新規CDKプロジェクト(App)の作成
まず、以下コマンドでCDK(TypeScript)のプロジェクトを作成します。
cdk init lib --language=typescript
パッケージをnpm install
package.json
に先ほどpushしたパッケージを指定します。
{
"name": "cdk-test",
"version": "0.1.0",
"bin": {
"cdk-test": "bin/cdk-test.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/node": "20.6.3",
"aws-cdk": "2.134.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "~5.2.2"
},
"dependencies": {
+ "@nakazato-cdk-assets/construct-lib": "^0.1.0",
"aws-cdk-lib": "2.134.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
.npmrcファイルを先ほどと同様に作成します。
@nakazato-cdk-assets:registry=https://${ドメイン名}/api/v4/projects/${プロジェクトID}/packages/npm/
//${ドメイン名}/api/v4/projects/1834/packages/npm/:_authToken="${NPM_TOKEN}"
npm installを実行します。
NPM_TOKEN=${先ほど作成したデプロイトークン} npm install @nakazato-cdk-assets/construct-lib
スタックファイルを以下のように修正します。
※CdkTestStackというスタックにした場合
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as customConstruct from '@nakazato-cdk-assets/construct-lib';
export class CdkTestStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new customConstruct.CustomBucket(this, 'CustomConstruct', {
bucketNamePrefix: 'nakazato-test',
});
}
}
S3バケットの作成
デプロイを実行して、S3バケットを作ります。
npx cdk deploy --all
✨ Synthesis time: 10.22s
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
IAM Statement Changes
┌───┬─────────────────────────────────────────────────┬────────┬─────────────────────────────────────────────────┬─────────────────────────────────────────────────┬────────────────────────────────────────────────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼─────────────────────────────────────────────────┼────────┼─────────────────────────────────────────────────┼─────────────────────────────────────────────────┼────────────────────────────────────────────────────┤
│ + │ ${CustomConstruct/nakazato-test-Bucket.Arn} │ Deny │ s3:* │ AWS:* │ "Bool": { │
│ │ ${CustomConstruct/nakazato-test-Bucket.Arn}/* │ │ │ │ "aws:SecureTransport": "false" │
│ │ │ │ │ │ } │
│ + │ ${CustomConstruct/nakazato-test-Bucket.Arn} │ Allow │ s3:DeleteObject* │ AWS:${Custom::S3AutoDeleteObjectsCustomResource │ │
│ │ ${CustomConstruct/nakazato-test-Bucket.Arn}/* │ │ s3:GetBucket* │ Provider/Role.Arn} │ │
│ │ │ │ s3:List* │ │ │
│ │ │ │ s3:PutBucketPolicy │ │ │
├───┼─────────────────────────────────────────────────┼────────┼─────────────────────────────────────────────────┼─────────────────────────────────────────────────┼────────────────────────────────────────────────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProv │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
│ │ ider/Role.Arn} │ │ │ │ │
└───┴─────────────────────────────────────────────────┴────────┴─────────────────────────────────────────────────┴─────────────────────────────────────────────────┴────────────────────────────────────────────────────┘
IAM Policy Changes
┌───┬───────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role} │ {"Fn::Sub":"arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"} │
└───┴───────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Do you wish to deploy these changes (y/n)? y
CdkTestStack: deploying... [1/1]
CdkTestStack: creating CloudFormation changeset...
CdkTestStack | 0/7 | 18:01:42 | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | CdkTestStack User Initiated
CdkTestStack | 0/7 | 18:01:48 | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | CdkTestStack User Initiated
CdkTestStack | 0/7 | 18:01:50 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
CdkTestStack | 0/7 | 18:01:50 | CREATE_IN_PROGRESS | AWS::S3::Bucket | CustomConstruct/nakazato-test-Bucket (CustomConstructnakazatotestBucket1EAD1A48)
CdkTestStack | 0/7 | 18:01:51 | CREATE_IN_PROGRESS | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092)
CdkTestStack | 0/7 | 18:01:52 | CREATE_IN_PROGRESS | AWS::S3::Bucket | CustomConstruct/nakazato-test-Bucket (CustomConstructnakazatotestBucket1EAD1A48) Resource creation Initiated
CdkTestStack | 0/7 | 18:01:52 | CREATE_IN_PROGRESS | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092) Resource creation Initiated
CdkTestStack | 0/7 | 18:01:52 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated
CdkTestStack | 1/7 | 18:01:52 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata)
CdkTestStack | 2/7 | 18:02:07 | CREATE_COMPLETE | AWS::S3::Bucket | CustomConstruct/nakazato-test-Bucket (CustomConstructnakazatotestBucket1EAD1A48)
CdkTestStack | 3/7 | 18:02:09 | CREATE_COMPLETE | AWS::IAM::Role | Custom::S3AutoDeleteObjectsCustomResourceProvider/Role (CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092)
CdkTestStack | 3/7 | 18:02:10 | CREATE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
CdkTestStack | 3/7 | 18:02:11 | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | CustomConstruct/nakazato-test-Bucket/Policy (CustomConstructnakazatotestBucketPolicy5CEEDA5F)
CdkTestStack | 3/7 | 18:02:12 | CREATE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F) Resource creation Initiated
CdkTestStack | 3/7 | 18:02:13 | CREATE_IN_PROGRESS | AWS::S3::BucketPolicy | CustomConstruct/nakazato-test-Bucket/Policy (CustomConstructnakazatotestBucketPolicy5CEEDA5F) Resource creation Initiated
CdkTestStack | 3/7 | 18:02:13 | CREATE_IN_PROGRESS | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F) Eventual consistency check initiated
CdkTestStack | 4/7 | 18:02:13 | CREATE_COMPLETE | AWS::S3::BucketPolicy | CustomConstruct/nakazato-test-Bucket/Policy (CustomConstructnakazatotestBucketPolicy5CEEDA5F)
CdkTestStack | 5/7 | 18:02:19 | CREATE_COMPLETE | AWS::Lambda::Function | Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler (CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F)
CdkTestStack | 5/7 | 18:02:19 | CREATE_IN_PROGRESS | Custom::S3AutoDeleteObjects | CustomConstruct/nakazato-test-Bucket/AutoDeleteObjectsCustomResource/Default (CustomConstructnakazatotestBucketAutoDeleteObjectsCustomResourceE418102A)
CdkTestStack | 5/7 | 18:02:21 | CREATE_IN_PROGRESS | Custom::S3AutoDeleteObjects | CustomConstruct/nakazato-test-Bucket/AutoDeleteObjectsCustomResource/Default (CustomConstructnakazatotestBucketAutoDeleteObjectsCustomResourceE418102A) Resource creation Initiated
CdkTestStack | 6/7 | 18:02:21 | CREATE_COMPLETE | Custom::S3AutoDeleteObjects | CustomConstruct/nakazato-test-Bucket/AutoDeleteObjectsCustomResource/Default (CustomConstructnakazatotestBucketAutoDeleteObjectsCustomResourceE418102A)
CdkTestStack | 7/7 | 18:02:22 | CREATE_COMPLETE | AWS::CloudFormation::Stack | CdkTestStack
✅ CdkTestStack
✨ Deployment time: 42.65s
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:***:stack/CdkTestStack/810a1610-d3e8-11ef-a582-06318d941fa5
✨ Total time: 52.87s
おわりに
今回は、AWS CDKのConstructを自作してgitlabにpushし、別リポジトリから利用してみることを試してみました!
どういった単位でConstructを作るか、などは人それぞれ考えがあるとは思いますが、チームで統一できていれば開発効率がかなり上がっていきそうですね