constructor()

in packages/cdk/lib/repository.ts [16:156]


	constructor(scope: App, id: string, props: GuStackProps) {
		super(scope, id, props);
		const githubActionsIAMRoleArn = new GuStringParameter(
			this,
			'GithubActionsIAMRoleArn',
			{
				description: 'IAM role for role used by github actions workflows',
			},
		);
		const deployToolsAccountNumber = new GuStringParameter(
			this,
			'DeployToolsAccount',
			{
				description:
					'Deploy tools account id - needed to give AMIgo access to this repository',
			},
		);
		const transcriptionRepository = new Repository(
			this,
			'TranscriptionServiceRepository',
			{
				repositoryName: `transcription-service`,
				// these are confusing - see https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html
				lifecycleRules: [
					// keep most recent 20 images tagged with 'main'
					{
						tagPrefixList: ['main'],
						maxImageCount: 20,
						rulePriority: 1,
					},
					// keep 10 most recent images not tagged with 'main'
					{
						maxImageCount: 10,
						rulePriority: 2,
					},
				],
				imageTagMutability: TagMutability.MUTABLE,
				removalPolicy: RemovalPolicy.DESTROY,
				imageScanOnPush: true,
			},
		);

		const mediaDownloadRepository = new Repository(
			this,
			'MediaDownloadRepository',
			{
				repositoryName: `transcription-service-media-download`,
				// these are confusing - see https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html
				lifecycleRules: [
					// keep most recent 20 images tagged with 'main'
					{
						tagPrefixList: ['main'],
						maxImageCount: 20,
						rulePriority: 1,
					},
					// keep 10 most recent images not tagged with 'main'
					{
						maxImageCount: 10,
						rulePriority: 2,
					},
				],
				imageTagMutability: TagMutability.MUTABLE,
				removalPolicy: RemovalPolicy.DESTROY,
				imageScanOnPush: true,
			},
		);
		// allow transcription workers read access to the repo
		const workerReadPolicyStatement = new PolicyStatement({
			principals: [
				new ArnPrincipal(Fn.importValue(`WorkerRoleArn-CODE`)),
				new ArnPrincipal(Fn.importValue(`WorkerRoleArn-PROD`)),
			],
			actions: [
				'ecr:GetAuthorizationToken',
				'ecr:BatchCheckLayerAvailability',
				'ecr:GetDownloadUrlForLayer',
				'ecr:GetRepositoryPolicy',
				'ecr:ListImages',
				'ecr:DescribeImages',
				'ecr:BatchGetImage',
			],
			effect: Effect.ALLOW,
		});
		transcriptionRepository.addToResourcePolicy(workerReadPolicyStatement);
		// allow github actions read/write access to the repo
		const githubReadWritePolicyStatement = new PolicyStatement({
			principals: [new ArnPrincipal(githubActionsIAMRoleArn.valueAsString)],
			actions: [
				'ecr:GetAuthorizationToken',
				'ecr:BatchCheckLayerAvailability',
				'ecr:GetDownloadUrlForLayer',
				'ecr:GetRepositoryPolicy',
				'ecr:DescribeRepositories',
				'ecr:ListImages',
				'ecr:DescribeImages',
				'ecr:BatchGetImage',
				'ecr:InitiateLayerUpload',
				'ecr:UploadLayerPart',
				'ecr:CompleteLayerUpload',
				'ecr:PutImage',
			],
			effect: Effect.ALLOW,
		});
		transcriptionRepository.addToResourcePolicy(githubReadWritePolicyStatement);
		mediaDownloadRepository.addToResourcePolicy(githubReadWritePolicyStatement);

		const repoAccessRole = new Role(this, 'RepoAccessRole', {
			roleName: 'TranscriptionServiceRepoAccessRole',
			assumedBy: new AccountPrincipal(deployToolsAccountNumber.valueAsString),
			inlinePolicies: {
				TranscriptionServiceRepoAccessPolicy: new PolicyDocument({
					statements: [
						new PolicyStatement({
							actions: ['ecr:GetAuthorizationToken'],
							resources: ['*'],
							effect: Effect.ALLOW,
						}),
						new PolicyStatement({
							actions: [
								'ecr:GetDownloadUrlForLayer',
								'ecr:BatchGetImage',
								'ecr:BatchCheckLayerAvailability',
								'ecr:DescribeImages',
								'ecr:ListImages',
								'ecr:GetDownloadUrlForLayer',
							],
							resources: [
								transcriptionRepository.repositoryArn,
								mediaDownloadRepository.repositoryArn,
							],
							effect: Effect.ALLOW,
						}),
					],
				}),
			},
		});

		new CfnOutput(this, 'AccessRoleArn', {
			value: repoAccessRole.roleArn,
		});
	}