-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.ts
138 lines (122 loc) · 3.82 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import * as path from 'path';
import * as codecommit from 'aws-cdk-lib/aws-codecommit';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as logs from 'aws-cdk-lib/aws-logs';
import { Construct } from 'constructs';
/**
* Properties for a CodeCommitMirror
*/
export interface CodeCommitMirrorProps {
/**
* The source repository
*/
readonly repository: CodeCommitMirrorSourceRepository;
/**
* The ECS cluster where to run the mirroring operation
*/
readonly cluster: ecs.ICluster;
/**
* The schedule for the mirroring operation
*
* @default - everyday at midnight
*/
readonly schedule?: events.Schedule;
/**
* Where to run the mirroring Fargate tasks
*
* @default - public subnets
*/
readonly subnetSelection?: ec2.SubnetSelection;
}
/**
* A source repository for AWS CodeCommit mirroring
*/
export abstract class CodeCommitMirrorSourceRepository {
/**
* Public GitHub repository
*/
public static gitHub(owner: string, name: string): CodeCommitMirrorSourceRepository {
return {
name,
plainTextUrl: `https://github.com/${owner}/${name}`,
};
}
/**
* Private repository with HTTPS clone URL stored in a AWS Secrets Manager secret or
* a AWS Systems Manager secure string parameter.
*
* @param name the repository name
* @param url the secret containing the HTTPS clone URL
*/
public static private(name: string, url: ecs.Secret): CodeCommitMirrorSourceRepository {
return {
name,
secretUrl: url,
};
}
/**
* The name of the repository
*/
public abstract readonly name: string;
/** The HTTPS clone URL in plain text, used for a public repository */
public abstract readonly plainTextUrl?: string;
/**
* The HTTPS clone URL if the repository is private.
*
* The secret should contain the username and/or token.
*
* @example
* `https://[email protected]/owner/name`
* `https://USERNAME:[email protected]/owner/name.git`
*/
public abstract readonly secretUrl?: ecs.Secret;
}
/**
* Mirror a repository to AWS CodeCommit on schedule
*/
export class CodeCommitMirror extends Construct {
constructor(scope: Construct, id: string, props: CodeCommitMirrorProps) {
super(scope, id);
const destination = new codecommit.Repository(this, 'Repository', {
repositoryName: props.repository.name,
description: `Mirror of ${props.repository.name}`,
});
const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDefinition');
taskDefinition.addContainer('Container', {
image: ecs.ContainerImage.fromAsset(path.join(__dirname, '..', '..', 'assets', 'codecommit-mirror', 'docker')),
logging: new ecs.AwsLogDriver({
streamPrefix: props.repository.name,
logRetention: logs.RetentionDays.TWO_MONTHS,
}),
environment: {
NAME: props.repository.name,
DESTINATION: destination.repositoryCloneUrlGrc,
...props.repository.plainTextUrl
? { SOURCE: props.repository.plainTextUrl }
: {},
},
secrets: props.repository.secretUrl
? { SOURCE: props.repository.secretUrl }
: undefined,
});
taskDefinition.addToTaskRolePolicy(new iam.PolicyStatement({
actions: ['codecommit:GitPush'],
resources: [destination.repositoryArn],
}));
const rule = new events.Rule(this, 'Rule', {
schedule: props.schedule ?? events.Schedule.cron({
minute: '0',
hour: '0',
}),
});
rule.addTarget(new targets.EcsTask({
cluster: props.cluster,
taskDefinition,
subnetSelection: props.subnetSelection ?? { subnetType: ec2.SubnetType.PUBLIC },
}));
}
}