実践課題
概要
ECR Repositoryではイメージタグの不変性(同一タグによる上書きを禁止)を有効化することができます。

Cloudformation及びCDKのL1コンストラクトでは ImageTagMutability というプロパティが提供されており、これを利用することでタグの不変性を設定することができます。
このパラメータはstring型ですが、許容される文字列は
MUTABLE(デフォルト)IMMUTABLE
の2つのみです。
使用例:
const repository = ecr.CfnRepository(this, 'MyRepository', { imageTagMutability: 'IMMUTABLE'})しかし、ワークショップ向けCDKのL2コンストラクト(ecr.Repository)では imageTagMutability がサポートされていません。そこで、L2コンストラクトに imageTagMutability プロパティを追加してみます。
目標
基本的な流れは4-機能追加PRの作成と同じです。
加えて、今回は特定の文字列のみしか入力を許容しないようにするため、独自のenum型を作成してみましょう。
export enum ImageTagMutability { MUTABLE = 'MUTABLE', IMMUTABLE = 'IMMUTABLE'}
export interface RepositoryProps { ..., // 既存のプロパティ readonly imageTagMutability?: ImageTagMutability;};このように定義することで、L2コンストラクトは以下のように呼び出すことができます。
const repository = new ecr.Repository(this, 'MyRepository', { imageTagMutability: ImageTagMutability.IMMUTABLE,})TypeScriptの型システムのおかげで、imageTagMutability には MUTABLE または IMMUTABLE のいずれかの文字列しか指定できないようになりました。
以上より、今回のPRには以下の内容を含める必要があります。
- L2コンストラクト(packages/aws-cdk-lib/aws-ecr/lib/repository.ts)のコード変更
ImageTagMutabilityenum型の追加RepositoryPropsにimageTagMutabilityプロパティを追加Repositoryクラスのconstructor関数中のCfnRepositoryクラスのインスタンス作成時にimageTagMutabilityプロパティを設定
- ユニットテスト(packages/aws-cdk-lib/aws-ecr/test/repository.test.ts)の追加
imageTagMutabilityプロパティがCloudformationテンプレートに正しく反映されるか
- 統合テスト(packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test)の追加
imageTagMutabilityを設定したECR Repositoryが正しく作成されるか
- READMEの更新
- 機能追加に関する説明を追加
手順
ブランチ作成
まずは、この機能追加用のブランチを作成します。
git switch -c add-image-tag-mutabilityL2コンストラクトのコード変更
ImageTagMutability enum型の追加
aws-cdk/packages/aws-cdk-lib/aws-ecr/lib/repository.tsを開き、ImageTagMutability enum型を追加します。
このとき、jsdocの記述も忘れないでください。
/** * The tag mutability setting for your repository. */export enum ImageTagMutability { /** * allow image tags to be overwritten. */ MUTABLE = 'MUTABLE', /** * all image tags within the repository will be immutable which will prevent them from being overwritten. */ IMMUTABLE = 'IMMUTABLE'}RepositoryPropsへimageTagMutabilityの追加
aws-cdk/packages/aws-cdk-lib/aws-ecr/lib/repository.tsを開き、RepositoryPropsにreadonlyなimageTagMutabilityプロパティを追加します。
export interface RepositoryProps { ..., // 既存のプロパティ /** * The tag mutability setting for the repository. * * If this parameter is omitted, the default setting of MUTABLE will be used which will allow image tags to be overwritten. * If IMMUTABLE is specified, all image tags within the repository will be immutable which will prevent them from being overwritten. * * @default ImageTagMutability.MUTABLE */ readonly imageTagMutability?: ImageTagMutability;};Repositoryクラスのconstructor関数の変更
Repositoryクラスのconstructor関数内で、CfnRepositoryクラスのインスタンス作成時にimageTagMutability引数を設定します。
export class Repository extends RepositoryBase { constructor(scope: Construct, id: string, props: RepositoryProps) { super(scope, id, props);
const resource = new CfnRepository(this, 'Resource', { ..., // 既存のプロパティ imageTagMutability: props.imageTagMutability }); };};以上で機能修正は完了です。一連の内容をcommitしておきましょう。
ユニットテストの追加
テストファイルの修正
続いてユニットテストを追加します。テストファイルはaws-cdk/packages/aws-cdk-lib/aws-ecr/test/repository.test.tsです。
ユニットテストでは、imageTagMutabilityプロパティがCloudformationテンプレートに正しく反映されるかを確認します。
test('specify imageTagMutability', () => { const stack = new cdk.Stack();
new ecr.Repository(stack, 'MyRepository', { imageTagMutability: ecr.ImageTagMutability.IMMUTABLE, });
Template.fromStack(stack).hasResourceProperties('AWS::ECR::Repository', { ImageTagMutability: 'IMMUTABLE', });});テストの実行
ユニットテストを実行して、テストが正常に通ることを確認します。
cd packages/aws-cdk-libyarn test aws-ecr/test/repository.test.tsこれでユニットテストの追加は完了です。一連の内容をcommitしておきましょう。
統合テストの追加
テストファイルの作成
続いて統合テストを追加します。統合テストでは、imageTagMutabilityを設定したecr repositoryが正しく作成されるかを確認します。
テストファイルはpackages/@aws-cdk-testing/framework-integ/test/aws-ecr/testに作成します。
今回は新規の統合テストファイルを作成します。
// packages/@aws-cdk-testing/framework-integ/test/aws-ecr/test/integ.ecr-image-tag-immutability.tsimport { App, Stack, StackProps } from 'aws-cdk-lib';import * as ecr from 'aws-cdk-lib/aws-ecr';import * as integ from '@aws-cdk/integ-tests-alpha';
// テスト用のStackを定義class TestStack extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props);
new ecr.Repository(this, 'MyRepository', { // imageTagMutabilityを設定 imageTagMutability: ecr.ImageTagMutability.IMMUTABLE, }); }}
const app = new App();
const stack = new TestStack(app, 'ImageTagMutabilityTestStack');
// 統合テストの実行new integ.IntegTest(app, 'EcrTest', { testCases: [stack],});統合テストの実行
統合テストを実行して、テストが正常に通ることを確認します。
# repositoryクラスを含めたecrのコンストラクトを再ビルドcd /packages/aws-cdk-libyarn tsc
cd packages/@aws-cdk-testing/framework-integ# integ ファイルのビルド/トランスパイルをして、javascript ファイルを生成yarn tsc# 実際にintegテストを実行するyarn integ aws-ecr/test/integ.ecr-image-tag-immutability.js --update-on-failed自動でCloudformationテンプレートの作成, スタックのデプロイ及び削除が行われます。エラーなく完了すれば統合テストも完了です。
作成したテストファイル及び生成されたスナップショットファイルをコミットしておきましょう。
READMEの更新
最後に、この機能追加に関する説明をREADMEに追加します。
### Image tag immutability
You can set tag immutability on images in our repository using the `imageTagMutability` construct prop.
```tsnew ecr.Repository(this, 'Repo', { imageTagMutability: ecr.ImageTagMutability.IMMUTABLE,});\```以上で必要な変更はすべて完了しました。
PRの提出
最後にPRを提出します。
PRルールに則り、以下のようなPRを作成しましょう。
| 項目 | 内容 | 記入例 |
|---|---|---|
| PRタイトル | PRの目的 | feat(ecr): add imageTagMutability property to a repository |
| Issue # (if applicable) | 関連するIssue番号 | Closes #2 |
| Reason for this change | 変更理由 | We can set an image tag immutability for an ecr repository from cloudformation, but this was not supported in the AWS CDK L2 construct. |
| Description of changes | 変更内容の詳細 | Add imageTagMutability property to repositoryProps and set it in the CfnRepository constructor. |
| Description of how you validated changes | 変更の検証方法 | Added both unit and integration tests. |
以上でPRの作成は完了です。おつかれさまでした!