Skip to content

Commit 0fed4db

Browse files
authored
CodeBuild Setup for GitHub Docker Image Builds (#2745)
### Description of changes: This is about one of three (or four) PRs that I need to parcel out to roll out this change. This first introduces the necessary CodeBuild project bits. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.
1 parent 483d379 commit 0fed4db

File tree

14 files changed

+391
-74
lines changed

14 files changed

+391
-74
lines changed

tests/ci/cdk/README.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ Use these commands if you wish to deploy individual stacks instead of the entire
134134

135135
1. Ensure you are in `aws-lc/tests/ci/cdk`
136136
2. Export the relevant environment variables:
137+
138+
If you wish deploy to your personal account:
139+
```shell
140+
# Ensure AWS Credentials are configured for your account and then execute
141+
eval "$(./run-cdk.sh --action clear-env)"
142+
eval "$(./run-cdk.sh --deploy-account ${DEPLOY_ACCOUNT_ID} --github-repo-owner ${GITHUB_REPO_OWNER} --action setup-dev-env)"
143+
```
144+
145+
If you wish to deploy to team account manually:
146+
```shell
147+
# Ensure the AWS credentials are configured for the pipeline account and then execute
148+
eval "$(./run-cdk.sh --action clear-env)"
149+
eval "$(./run-cdk.sh --action setup-prod-env)"
150+
```
151+
137152
- `DEPLOY_ACCOUNT_ID` (required): AWS account you wish to deploy the CI stacks to
138153
- `GITHUB_REPO_OWNER` (required): the GitHub repo targeted by this CI setup.
139154

@@ -148,27 +163,39 @@ Use these commands if you wish to deploy individual stacks instead of the entire
148163
```
149164
Set EC2-VPC Elastic IPs = 20 (default is only 5)
150165

166+
4. Synthesize the Cloudformation Stacks
167+
```shell
168+
cdk synth
169+
```
151170

152171
4. Choose 1 of the following command options:
153-
- To set up AWS-LC CI, run command:
172+
- List the stacks available for deployment
154173
```shell
155-
./run-cdk.sh --github-repo-owner ${GITHUB_REPO_OWNER} --action deploy-ci --deploy-account ${DEPLOY_ACCOUNT_ID}
174+
cdk list
156175
```
157176

158-
- To update AWS-LC CI, run command:
177+
- Example: To setup or update AWS-LC Docker Repositories:
159178
```shell
160-
./run-cdk.sh --github-repo-owner ${GITHUB_REPO_OWNER} --action update-ci --deploy-account ${DEPLOY_ACCOUNT_ID}
179+
# Replace Dev with Staging or Prod as neccessary
180+
cdk deploy AwsLcCiPipeline/Dev-EcrRepositories/aws-lc-private-ecr-stack
161181
```
162-
- To create/update Linux Docker images, run command:
182+
183+
- Example: To set up or deploy AWS-LC CI stacks, run command:
163184
```shell
164-
./run-cdk.sh --github-repo-owner ${GITHUB_REPO_OWNER} --action build-linux-img --deploy-account ${DEPLOY_ACCOUNT_ID}
185+
# Replace Dev with Staging or Prod as neccessary
186+
cdk deploy AwsLcCiPipeline/Dev-CiTests/aws-lc-ci-*
165187
```
166188

167-
- To destroy AWS-LC CI resources created above, run command:
189+
- Example: To setup or deploy AWS-LC GitHub Actions:
190+
```shell
191+
# Replace Dev with Staging or Prod as neccessary
192+
cdk deploy AwsLcCiPipeline/Dev-GithubActions/*
193+
```
194+
- To destroy all CDK resources run command (NOTE: this command will destroy all resources (AWS CodeBuild and ECR).):
168195
```shell
169-
./run-cdk.sh --github-repo-owner ${GITHUB_REPO_OWNER} --action destroy-ci --deploy-account ${DEPLOY_ACCOUNT_ID}
196+
# Replace Dev with Staging or Prod as neccessary
197+
cdk destroy AwsLcCiPipeline/Dev-*
170198
```
171-
NOTE: this command will destroy all resources (AWS CodeBuild and ECR).
172199

173200
For help, run command:
174201
```

tests/ci/cdk/app.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,8 @@
1111
from cdk.windows_docker_image_build_stack import WindowsDockerImageBuildStack
1212
from cdk.ecr_stack import EcrStack
1313
from util.metadata import (
14-
LINUX_X86_ECR_REPO,
15-
LINUX_AARCH_ECR_REPO,
16-
WINDOWS_X86_ECR_REPO,
1714
PIPELINE_ACCOUNT,
1815
PIPELINE_REGION,
19-
DEPLOY_ACCOUNT,
20-
DEPLOY_REGION,
2116
)
2217

2318
# Initialize app.
@@ -29,23 +24,4 @@
2924
env=Environment(account=PIPELINE_ACCOUNT, region=PIPELINE_REGION),
3025
)
3126

32-
if DEPLOY_ACCOUNT and DEPLOY_REGION:
33-
# Initialize env.
34-
env = Environment(account=DEPLOY_ACCOUNT, region=DEPLOY_REGION)
35-
36-
# Define AWS ECR stacks.
37-
# ECR holds the docker images, which are pre-built to accelerate the code builds/tests of git pull requests.
38-
EcrStack(app, "aws-lc-ecr-linux-x86", LINUX_X86_ECR_REPO, env=env)
39-
EcrStack(app, "aws-lc-ecr-linux-aarch", LINUX_AARCH_ECR_REPO, env=env)
40-
EcrStack(app, "aws-lc-ecr-windows-x86", WINDOWS_X86_ECR_REPO, env=env)
41-
42-
# Define CodeBuild Batch job for building Docker images.
43-
LinuxDockerImageBatchBuildStack(app, "aws-lc-docker-image-build-linux", env=env)
44-
45-
# AWS CodeBuild cannot build Windows Docker images because DIND (Docker In Docker) is not supported on Windows.
46-
# Windows Docker images are created by running commands in Windows EC2 instance.
47-
WindowsDockerImageBuildStack(app, "aws-lc-docker-image-build-windows", env=env)
48-
49-
add_ci_stacks(app, env=env)
50-
5127
app.synth()

tests/ci/cdk/cdk/aws_lc_github_actions_stack.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
from aws_cdk import (
66
Duration,
7-
Stack,
87
aws_codebuild as codebuild,
98
aws_iam as iam,
10-
aws_s3_assets,
119
aws_logs as logs,
10+
aws_ecr as ecr,
1211
Environment,
1312
)
1413
from constructs import Construct
@@ -18,7 +17,7 @@
1817
from util.iam_policies import (
1918
code_build_publish_metrics_in_json,
2019
)
21-
from util.metadata import LINUX_X86_ECR_REPO, LINUX_AARCH_ECR_REPO, WINDOWS_X86_ECR_REPO
20+
from util.metadata import AMAZONLINUX_ECR_REPO, CENTOS_ECR_REPO, FEDORA_ECR_REPO, LINUX_X86_ECR_REPO, LINUX_AARCH_ECR_REPO, UBUNTU_ECR_REPO, WINDOWS_X86_ECR_REPO
2221

2322
class AwsLcGitHubActionsStack(AwsLcBaseCiStack):
2423
"""Define a stack used to execute AWS-LC self-hosted GitHub Actions Runners."""
@@ -32,6 +31,12 @@ def __init__(
3231
) -> None:
3332
super().__init__(scope, id, env=env, timeout=180, **kwargs)
3433

34+
# TODO: First 3 indices ordering is important for now as they are referenced directly for now.
35+
repo_names = [LINUX_X86_ECR_REPO, LINUX_AARCH_ECR_REPO, WINDOWS_X86_ECR_REPO, UBUNTU_ECR_REPO,
36+
AMAZONLINUX_ECR_REPO, CENTOS_ECR_REPO, FEDORA_ECR_REPO]
37+
ecr_repos = [ecr.Repository.from_repository_name(self, x.replace('/', '-'), repository_name=x)
38+
for x in repo_names]
39+
3540
# Define a IAM role for this stack.
3641
metrics_policy = iam.PolicyDocument.from_json(
3742
code_build_publish_metrics_in_json(env)
@@ -55,12 +60,7 @@ def __init__(
5560
"ecr:BatchCheckLayerAvailability",
5661
"ecr:GetDownloadUrlForLayer",
5762
],
58-
resources=[
59-
"arn:aws:ecr:{}:{}:repository/{}"
60-
.format(env.region, env.account, repo) for repo in [LINUX_X86_ECR_REPO,
61-
LINUX_AARCH_ECR_REPO,
62-
WINDOWS_X86_ECR_REPO]
63-
],
63+
resources=[x.repository_arn for x in ecr_repos],
6464
),
6565
],
6666
)
@@ -105,16 +105,18 @@ def __init__(
105105
environment_variables={
106106
"AWS_ACCOUNT_ID": codebuild.BuildEnvironmentVariable(value=env.account),
107107
"AWS_ECR_REPO_LINUX_X86": codebuild.BuildEnvironmentVariable(
108-
value="{}.dkr.ecr.{}.amazonaws.com/{}".format(env.account, env.region, LINUX_X86_ECR_REPO)
108+
value=ecr_repos[0].repository_uri
109109
),
110110
"AWS_ECR_REPO_LINUX_AARCH": codebuild.BuildEnvironmentVariable(
111-
value="{}.dkr.ecr.{}.amazonaws.com/{}".format(env.account, env.region, LINUX_AARCH_ECR_REPO)
111+
value=ecr_repos[1].repository_uri
112112
),
113113
"AWS_ECR_REPO_WINDOWS_X86": codebuild.BuildEnvironmentVariable(
114-
value="{}.dkr.ecr.{}.amazonaws.com/{}".format(env.account, env.region, WINDOWS_X86_ECR_REPO)
114+
value=ecr_repos[2].repository_uri
115115
),
116+
"ECR_REGISTRY_URL": codebuild.BuildEnvironmentVariable(value=ecr_repos[0].registry_uri),
116117
},
117118
),
119+
# TODO: We can do away with this if we use aws-actions/amazon-ecr-login@v2, just need to migrate
118120
build_spec=codebuild.BuildSpec.from_object({
119121
"version": 0.2,
120122
"phases": {

tests/ci/cdk/cdk/aws_lc_github_ci_stack.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44

55
from aws_cdk import (
66
Duration,
7-
Stack,
87
aws_codebuild as codebuild,
98
aws_iam as iam,
10-
aws_s3_assets,
119
aws_logs as logs,
1210
Environment,
1311
)
@@ -20,17 +18,8 @@
2018
code_build_publish_metrics_in_json,
2119
code_build_cloudwatch_logs_policy_in_json,
2220
)
23-
from util.metadata import (
24-
GITHUB_PUSH_CI_BRANCH_TARGETS,
25-
GITHUB_REPO_OWNER,
26-
GITHUB_REPO_NAME,
27-
PRE_PROD_ACCOUNT,
28-
STAGING_GITHUB_REPO_OWNER,
29-
STAGING_GITHUB_REPO_NAME,
30-
)
3121
from util.build_spec_loader import BuildSpecLoader
3222

33-
3423
class AwsLcGitHubCIStack(AwsLcBaseCiStack):
3524
"""Define a stack used to batch execute AWS-LC tests in GitHub."""
3625

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC
3+
import itertools
4+
import typing
5+
6+
from aws_cdk import (
7+
Duration,
8+
aws_codebuild as codebuild,
9+
aws_iam as iam,
10+
aws_logs as logs,
11+
aws_ecr as ecr,
12+
Environment,
13+
)
14+
from constructs import Construct
15+
16+
from cdk.aws_lc_base_ci_stack import AwsLcBaseCiStack
17+
from util.iam_policies import (
18+
code_build_publish_metrics_in_json,
19+
)
20+
from util.metadata import UBUNTU_ECR_REPO, AMAZONLINUX_ECR_REPO, CENTOS_ECR_REPO, FEDORA_ECR_REPO
21+
22+
class AwsLcGitHubDockerActionsStack(AwsLcBaseCiStack):
23+
"""Define a stack used to execute AWS-LC self-hosted GitHub Actions Runners on Docker Images."""
24+
25+
def __init__(
26+
self,
27+
scope: Construct,
28+
id: str,
29+
env: typing.Union[Environment, typing.Dict[str, typing.Any]],
30+
**kwargs
31+
) -> None:
32+
super().__init__(scope, id, env=env, timeout=180, **kwargs)
33+
34+
# Define a IAM role for this stack.
35+
metrics_policy = iam.PolicyDocument.from_json(
36+
code_build_publish_metrics_in_json(env)
37+
)
38+
39+
repo_names = [UBUNTU_ECR_REPO, AMAZONLINUX_ECR_REPO, CENTOS_ECR_REPO, FEDORA_ECR_REPO]
40+
ecr_repos = [ecr.Repository.from_repository_name(self, x.replace('/', '-'), repository_name=x)
41+
for x in repo_names]
42+
43+
staging_repo = ecr.Repository(self, "aws-lc-ecr-staging",
44+
image_tag_mutability=ecr.TagMutability.IMMUTABLE,
45+
lifecycle_rules=[ecr.LifecycleRule(
46+
max_image_age=Duration.days(7),
47+
)])
48+
49+
ecr_repos.append(staging_repo)
50+
51+
inline_policies = {
52+
"metrics_policy": metrics_policy,
53+
"ecr": iam.PolicyDocument(
54+
statements=[
55+
iam.PolicyStatement(
56+
effect=iam.Effect.ALLOW,
57+
actions=[
58+
"ecr:GetAuthorizationToken",
59+
],
60+
resources=["*"],
61+
),
62+
iam.PolicyStatement(
63+
effect=iam.Effect.ALLOW,
64+
actions=[
65+
"ecr:BatchGetImage",
66+
"ecr:BatchCheckLayerAvailability",
67+
"ecr:CompleteLayerUpload",
68+
"ecr:GetDownloadUrlForLayer",
69+
"ecr:InitiateLayerUpload",
70+
"ecr:PutImage",
71+
"ecr:UploadLayerPart",
72+
],
73+
resources=[x for x in itertools.chain([
74+
x.repository_arn for x in ecr_repos
75+
], [ecr.Repository.from_repository_name(self, "quay-io", "quay.io/*").repository_arn])],
76+
),
77+
],
78+
)
79+
}
80+
role = iam.Role(
81+
scope=self,
82+
id="{}-role".format(id),
83+
assumed_by=iam.ServicePrincipal("codebuild.amazonaws.com"),
84+
inline_policies=inline_policies,
85+
)
86+
87+
logging_options = codebuild.LoggingOptions(
88+
cloud_watch=codebuild.CloudWatchLoggingOptions(log_group=logs.LogGroup(
89+
self, id="{}-logs".format(id)))
90+
)
91+
92+
# Override base class provided configuration
93+
self.git_hub_source = codebuild.Source.git_hub(
94+
owner=self.github_repo_owner,
95+
repo=self.github_repo_name,
96+
webhook=True,
97+
webhook_filters=[
98+
codebuild.FilterGroup.in_event_of(
99+
codebuild.EventAction.WORKFLOW_JOB_QUEUED
100+
),
101+
],
102+
)
103+
104+
# Define CodeBuild.
105+
project = codebuild.Project(
106+
scope=self,
107+
id=id,
108+
project_name=id,
109+
source=self.git_hub_source,
110+
role=role,
111+
timeout=Duration.minutes(self.timeout),
112+
logging=logging_options,
113+
environment=codebuild.BuildEnvironment(
114+
compute_type=codebuild.ComputeType.SMALL,
115+
privileged=True,
116+
build_image=codebuild.LinuxBuildImage.STANDARD_7_0,
117+
environment_variables={
118+
"AWS_ACCOUNT_ID": codebuild.BuildEnvironmentVariable(value=env.account),
119+
"ECR_REGISTRY_URL": codebuild.BuildEnvironmentVariable(value=staging_repo.registry_uri),
120+
"ECR_STAGING_REPO": codebuild.BuildEnvironmentVariable(value=staging_repo.repository_uri),
121+
},
122+
),
123+
)
124+
125+
cfn_project = project.node.default_child
126+
cfn_project.add_property_override("Triggers.PullRequestBuildPolicy", self.pull_request_policy)

0 commit comments

Comments
 (0)