export function addRefreshMaterializedViewLambda()

in packages/cdk/lib/refresh-materialized-view.ts [18:77]


export function addRefreshMaterializedViewLambda(
	scope: GuStack,
	props: RefreshMaterializedViewLambdaProps,
) {
	const app = 'refresh-materialized-view';

	const { vpc, dbAccess, db } = props;

	const lambda = new GuLambdaFunction(scope, 'RefreshMaterializedView', {
		app,
		vpc,
		architecture: Architecture.ARM_64,
		securityGroups: [dbAccess],
		fileName: `${app}.zip`,
		handler: 'index.main',
		environment: {
			DATABASE_HOSTNAME: db.dbInstanceEndpointAddress,
			QUERY_LOGGING: 'false', // Set this to 'true' to enable SQL query logging
		},
		runtime: Runtime.NODEJS_20_X,
		timeout: Duration.minutes(10),
	});

	// This sort of lookup is a bit fragile!
	// TODO pass the tasks in as a prop
	const awsTasks = scope.node.children
		.filter((_): _ is ScheduledFargateTask => _ instanceof ScheduledFargateTask)
		.filter((_) => _.taskDefinition.family.includes('Aws'));

	if (awsTasks.length === 0) {
		// This is only seen at synth time. It doesn't impact running infrastructure.
		throw new Error(`Could not find any 'Aws' tasks`);
	}

	awsTasks.forEach((task) => {
		// Invoke the lambda when the task has completed successfully
		new Rule(scope, `${app}-lambda-trigger-${task.taskDefinition.family}`, {
			targets: [new LambdaFunction(lambda)],
			enabled: true,
			eventPattern: {
				source: ['aws.ecs'],
				detailType: ['ECS Task State Change'],

				// See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Task.html
				detail: {
					clusterArn: [task.cluster.clusterArn],
					taskDefinitionArn: [task.taskDefinition.taskDefinitionArn],
					lastStatus: ['STOPPED'],
					stopCode: ['EssentialContainerExited'], // The CloudQuery container is the "essential" one
					'containers.exitCode': [{ numeric: ['=', 0] }],
					'containers.name': [
						task.taskDefinition.defaultContainer?.containerName,
					],
				},
			},
		});
	});

	db.grantConnect(lambda, 'refresh_materialized_view');
}