コンテンツにスキップ

実践課題

概要

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

ecr-tag-immutability

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)のコード変更
    • ImageTagMutability enum型の追加
    • RepositoryPropsimageTagMutabilityプロパティを追加
    • 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の更新
    • 機能追加に関する説明を追加

手順

ブランチ作成

まずは、この機能追加用のブランチを作成します。

Terminal window
git switch -c add-image-tag-mutability

L2コンストラクトのコード変更

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'
}

RepositoryPropsimageTagMutabilityの追加

aws-cdk/packages/aws-cdk-lib/aws-ecr/lib/repository.tsを開き、RepositoryPropsreadonlyimageTagMutabilityプロパティを追加します。

aws-cdk/packages/aws-cdk-lib/aws-ecr/lib/repository.ts
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引数を設定します。

aws-cdk/packages/aws-cdk-lib/aws-ecr/lib/repository.ts
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テンプレートに正しく反映されるかを確認します。

aws-cdk/packages/aws-cdk-lib/aws-ecr/test/repository.test.ts
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',
});
});

テストの実行

ユニットテストを実行して、テストが正常に通ることを確認します。

Terminal window
cd packages/aws-cdk-lib
yarn 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.ts
import { 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],
});

統合テストの実行

統合テストを実行して、テストが正常に通ることを確認します。

Terminal window
# repositoryクラスを含めたecrのコンストラクトを再ビルド
cd /packages/aws-cdk-lib
yarn 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に追加します。

aws-cdk/packages/aws-cdk-lib/aws-ecr/README.md
### Image tag immutability
You can set tag immutability on images in our repository using the `imageTagMutability` construct prop.
```ts
new 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の作成は完了です。おつかれさまでした!