Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to CodeBuild batch. #51

Merged
merged 28 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e98c2a4
Add batch build spec.
bryce-shang Sep 24, 2020
40bdc04
Use batch-list.
bryce-shang Sep 24, 2020
8cef920
Remove invalid characters from identifier.
bryce-shang Sep 24, 2020
375b429
Fix syntax warning.
bryce-shang Sep 24, 2020
e5b02c3
Upgrade cdk to latest version 1.64.
bryce-shang Sep 24, 2020
78670a3
Add github_codebuild_batch_stack.py.
bryce-shang Sep 25, 2020
29c2a1f
Move build specs.
bryce-shang Sep 25, 2020
955546f
Refactor cdk code.
bryce-shang Sep 25, 2020
0348b69
Use aws-lc AWS account.
bryce-shang Sep 29, 2020
c0884c7
Unify default values of env variable.
bryce-shang Sep 29, 2020
b99f532
Fix windows docker build issue.
bryce-shang Sep 29, 2020
2320c00
Add s3 bucket deletion when destroy resource.
bryce-shang Sep 29, 2020
9c10400
Add new variable github_source_version.
bryce-shang Sep 29, 2020
a72c367
Upgrade ec2 windows from 2016 to 2019.
bryce-shang Sep 29, 2020
65df870
Add git to PATH.
bryce-shang Sep 29, 2020
6b6470d
Revert "Upgrade ec2 windows from 2016 to 2019."
bryce-shang Sep 29, 2020
967650a
Add 2019 windows.
bryce-shang Sep 30, 2020
201fbfa
Move cyg and quilt installation to build spec.
bryce-shang Sep 30, 2020
dff001b
Add docker image build doc.
bryce-shang Sep 30, 2020
eb8ef5e
Fix identifier name.
bryce-shang Sep 30, 2020
bf51664
Switch to 2016. CodeBuild does not support 2019.
bryce-shang Sep 30, 2020
8ff3047
Clean up and add more docs.
bryce-shang Sep 30, 2020
6d51e28
Fix typo.
bryce-shang Oct 2, 2020
c5cc6be
Modify README.md
bryce-shang Oct 2, 2020
643edb5
Remove '*'.
bryce-shang Oct 2, 2020
2b710d9
Change privileged-mode to false.
bryce-shang Oct 2, 2020
a56d03d
ARM sanitizer needs privileged-mode.
bryce-shang Oct 5, 2020
825a473
Merge branch 'main' into batch-ci
bryce-shang Oct 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 60 additions & 5 deletions tests/ci/cdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ To setup or update the CI in your account you will need the following IAM permis
* codebuild:Create*
* codebuild:Update*
* codebuild:Batch*
* codebuild:StartBuild
* codebuild:StopBuild
* codebuild:RetryBuild
* EC2
* ec2:Describe*
* ec2:Create*
Expand Down Expand Up @@ -86,17 +89,15 @@ Below is CI file structure.
├── cdk
│   ├── __init__.py
│   ├── ecr_stack.py
│   ├── github_codebuild_stack.py
│   ├── linux_docker_images_build_stack.py
│   ├── windows_docker_build_ssm_document.yaml
│   └── windows_docker_image_build_stack.py
│   ├── ...
├── cdk.json
├── requirements.txt
├── run-cdk.sh
├── setup.py
└── util
├── __init__.py
└── util.py
└── env_util.py
└── ...
```
* `README.md` — The introductory README for this project.
* `app.py` — The “main” for this sample application.
Expand Down Expand Up @@ -158,3 +159,57 @@ command.
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk docs` open CDK documentation

### Useful Docker image build commands
bryce-shang marked this conversation as resolved.
Show resolved Hide resolved

**Notes**:
* below commands replicate steps that are performed in `run-cdk.sh` but use default values set in `cdk/util/metadata.py`.
* Always clean up resources set up for Docker image build.
* `cdk destroy aws-lc-docker-image-build-* --force`

#### Linux Docker image build

```bash
# Launch Linux Docker image CodeBuild resources.
cdk deploy aws-lc-docker-image-build-linux --require-approval never

# Trigger CodeBuild to build Linux Docker Images
aws codebuild start-build-batch --project-name aws-lc-docker-image-build-linux

# Go to AWS console, you can check CodeBuild by clicking "Developer Tools > CodeBuild > Build projects".
```

#### Windows Docker image build
Windows docker image build requires more resources (like EC2 host, S3, SSM and so on) set up because DIND (Docker in Docker) is not supported by Windows.
Below are some commands specific to windows docker image build.

```bash
# Define environment variables needed by Windows docker image build.
export DATE_NOW="$(date +%Y-%m-%d-%H-%M)"
export S3_FOR_WIN_DOCKER_IMG_BUILD="${AWS_LC_S3_BUCKET_PREFIX}-${DATE_NOW}"
export WIN_EC2_TAG_KEY="aws-lc"
export WIN_EC2_TAG_VALUE="aws-lc-windows-docker-image-build-${DATE_NOW}"
export WIN_DOCKER_BUILD_SSM_DOCUMENT="windows-ssm-document-${DATE_NOW}"

# Clean up all Windows docker image build resources.
cdk destroy aws-lc-docker-image-build-windows --force
aws s3 rm "s3://${S3_FOR_WIN_DOCKER_IMG_BUILD}" --recursive
aws s3api delete-bucket --bucket "${S3_FOR_WIN_DOCKER_IMG_BUILD}"

# Deploy Windows docker image build resources.
cdk deploy aws-lc-docker-image-build-windows --require-approval never

# Sleep 10 minutes so Windows EC2 is ready to execute SSM commands.
sleep 600

# Trigger SSM commands to build Windows Docker Images.
instance_id=$(aws ec2 describe-instances \
--filters "Name=tag:${WIN_EC2_TAG_KEY},Values=${WIN_EC2_TAG_VALUE}" | jq -r '.Reservations[0].Instances[0].InstanceId')
aws ssm send-command \
--instance-ids "${instance_id}" \
--document-name "${WIN_DOCKER_BUILD_SSM_DOCUMENT}" \
--output-s3-bucket-name "${S3_FOR_WIN_DOCKER_IMG_BUILD}" \
--output-s3-key-prefix 'ssm-runcommand-logs'

# Go to AWS console, you can check run command by clicking `AWS Systems Manager > Run Command`.
```
165 changes: 12 additions & 153 deletions tests/ci/cdk/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,170 +5,29 @@

from aws_cdk import core

from cdk.github_codebuild_stack import GitHubCodeBuildStack
from cdk.linux_docker_images_build_stack import LinuxDockerImagesBuildStack
from cdk.aws_lc_github_ci_stack import AwsLcGitHubCIStack
from cdk.linux_docker_image_batch_build_stack import LinuxDockerImageBatchBuildStack
from cdk.windows_docker_image_build_stack import WindowsDockerImageBuildStack
from cdk.ecr_stack import EcrStack
from util.util import EnvUtil
from util.metadata import LINUX_X86_ECR_REPO, LINUX_AARCH_ECR_REPO, WINDOWS_ECR_REPO

# Initialize app.
app = core.App()

# Fetch environment variables.
aws_account = EnvUtil.get("CDK_DEPLOY_ACCOUNT", "620771051181")
aws_region = EnvUtil.get("CDK_DEPLOY_REGION", "us-west-2")
env = {"account": aws_account, "region": aws_region}

# Define AWS ECR stacks.
# ECR holds the docker images, which are pre-built to accelerate the code builds/tests of git pull requests.
linux_aarch_ecr_repo = EnvUtil.get("ECR_LINUX_AARCH_REPO_NAME", "aws-lc-test-docker-images-linux-aarch")
linux_x86_ecr_repo = EnvUtil.get("ECR_LINUX_X86_REPO_NAME", "aws-lc-test-docker-images-linux-x86")
windows_ecr_repo = EnvUtil.get("ECR_WINDOWS_REPO_NAME", "aws-lc-test-docker-images-windows")
EcrStack(app, linux_aarch_ecr_repo, env=env)
EcrStack(app, linux_x86_ecr_repo, env=env)
EcrStack(app, windows_ecr_repo, env=env)
EcrStack(app, "aws-lc-ecr-linux-x86", LINUX_X86_ECR_REPO)
EcrStack(app, "aws-lc-ecr-linux-aarch", LINUX_AARCH_ECR_REPO)
EcrStack(app, "aws-lc-ecr-windows", WINDOWS_ECR_REPO)

# Define CodeBuild Batch job for testing code.
LinuxDockerImageBatchBuildStack(app, "aws-lc-docker-image-build-linux")

# Define stacks used to build Docker images.
linux_docker_img_build_stacks = [
{
"id": "aws-lc-test-docker-images-build-linux-aarch",
"repo_name": linux_aarch_ecr_repo,
"env_type": "ARM",
"build_spec": "linux-aarch-docker-img-build.yml"
},
{
"id": "aws-lc-test-docker-images-build-linux-x86",
"repo_name": linux_x86_ecr_repo,
"env_type": "Linux",
"build_spec": "linux-x86-docker-img-build.yml"
}
]
code_build_dir = "./tests/ci/codebuild"
for stack in linux_docker_img_build_stacks:
LinuxDockerImagesBuildStack(app, stack["id"], stack["repo_name"],
"./tests/ci/codebuild/{}".format(stack["build_spec"]), env_type=stack["env_type"],
env=env)
# DIND is not supported on Windows and, therefore, AWS CodeBuild is not used to build Windows Server container images.
# Windows Docker images are created by running commands in Windows EC2 instance.
WindowsDockerImageBuildStack(app, "aws-lc-test-docker-images-build-windows", windows_ecr_repo, env=env)
WindowsDockerImageBuildStack(app, "aws-lc-docker-image-build-windows")

# Define CodeBuild stacks used to run test cases.
is_windows = True
# Define CodeBuild running on Linux aarch.
linux_aarch_test_stacks = [
{
"id": "aws-lc-test-ubuntu-19-10--gcc-9x",
"img": "ubuntu-19.10_gcc-9x_latest",
"spec": "ubuntu-19.10_gcc-9x_aarch64.yml",
},
{
"id": "aws-lc-test-ubuntu-19-10--clang-9x",
"img": "ubuntu-19.10_clang-9x_latest",
"spec": "ubuntu-19.10_clang-9x_aarch64.yml",
},
]
for stack in linux_aarch_test_stacks:
GitHubCodeBuildStack(app, stack["id"], linux_aarch_ecr_repo, stack["img"],
"./tests/ci/codebuild/{}".format(stack["spec"]), env_type="ARM", privileged=True, env=env)
# Define CodeBuild running on Linux x86-64.
linux_x86_test_stacks = [
{
"id": "aws-lc-test-pre-push",
"img": "ubuntu-18.04_gcc-7x_latest",
"spec": "pre-push.yml",
},
{
"id": "aws-lc-test-ubuntu-16-04--gcc-5x--x86",
"img": "ubuntu-16.04_gcc-5x_latest",
"spec": "ubuntu-16.04_gcc-5x_x86.yml",
},
{
"id": "aws-lc-test-ubuntu-18-04--clang-6x--x86-64",
"img": "ubuntu-18.04_clang-6x_latest",
"spec": "ubuntu-18.04_clang-6x_x86-64.yml",
},
{
"id": "aws-lc-test-ubuntu-18-04--gcc-7x--x86-64",
"img": "ubuntu-18.04_gcc-7x_latest",
"spec": "ubuntu-18.04_gcc-7x_x86-64.yml",
},
{
"id": "aws-lc-test-ubuntu-19-10--gcc-9x--x86-64",
"img": "ubuntu-19.10_gcc-9x_latest",
"spec": "ubuntu-19.10_gcc-9x_x86-64.yml",
},
{
"id": "aws-lc-test-ubuntu-19-10--clang-9x--x86-64",
"img": "ubuntu-19.10_clang-9x_latest",
"spec": "ubuntu-19.10_clang-9x_x86-64.yml",
},
{
"id": "aws-lc-test-ubuntu-19-04--gcc-8x--x86-64",
"img": "ubuntu-19.04_gcc-8x_latest",
"spec": "ubuntu-19.04_gcc-8x_x86-64.yml",
},
{
"id": "aws-lc-test-ubuntu-19-04--clang-8x--x86-64",
"img": "ubuntu-19.04_clang-8x_latest",
"spec": "ubuntu-19.04_clang-8x_x86-64.yml",
},
{
"id": "aws-lc-test-centos-7--gcc-4x--x86",
"img": "centos-7_gcc-4x_latest",
"spec": "centos-7_gcc-4x-x86.yml",
},
{
"id": "aws-lc-test-centos-7--gcc-4x--x86-64",
"img": "centos-7_gcc-4x_latest",
"spec": "centos-7_gcc-4x-x86-64.yml",
},
{
"id": "aws-lc-test-amazonlinux-2--gcc-7x--x86-64",
"img": "amazonlinux-2_gcc-7x_latest",
"spec": "amazonlinux-2_gcc-7x-x86-64.yml",
},
{
"id": "aws-lc-test-s2n--integration",
"img": "s2n_integration_clang-9x_latest",
"spec": "s2n_integration.yml",
},
{
"id": "aws-lc-test-fedora-31--gcc-9x",
"img": "fedora-31_gcc-9x_latest",
"spec": "fedora-31_gcc-9x_x86-64.yml",
},
{
"id": "aws-lc-test-fedora-31--clang-9x",
"img": "fedora-31_clang-9x_latest",
"spec": "fedora-31_clang-9x_x86-64.yml",
},
]
for stack in linux_x86_test_stacks:
GitHubCodeBuildStack(app, stack["id"], linux_x86_ecr_repo, stack["img"],
"./tests/ci/codebuild/{}".format(stack["spec"]), privileged=True, env=env)
# Define CodeBuild for sanitizer tests.
linux_sanitizer_test_stacks = [
{
"id": "aws-lc-test-ubuntu-19-10--clang-9x--sanitizer",
"img": "ubuntu-19.10_clang-9x_sanitizer_latest",
"spec": "ubuntu-19.10_clang-9x_aarch64_sanitizer.yml",
"env_type": "ARM",
"repo": linux_aarch_ecr_repo,
},
{
"id": "aws-lc-test-ubuntu-19-10--clang-9x--x86-64--sanitizer",
"img": "ubuntu-19.10_clang-9x_sanitizer_latest",
"spec": "ubuntu-19.10_clang-9x_x86-64_sanitizer.yml",
"env_type": "Linux",
"repo": linux_x86_ecr_repo,
},
]
for stack in linux_sanitizer_test_stacks:
GitHubCodeBuildStack(app, stack["id"], stack["repo"], stack["img"],
"./tests/ci/codebuild/{}".format(stack["spec"]), env_type=stack["env_type"], privileged=True,
env=env)
# Define CodeBuild running on Windows.
GitHubCodeBuildStack(app, "aws-lc-test-windows-msvc2015-x64--vs2015", windows_ecr_repo, "vs2015_latest",
"./tests/ci/codebuild/windows-msvc2015-x64.yml", env_type="Windows", env=env)
# Define CodeBuild Batch job for testing code.
AwsLcGitHubCIStack(app, "aws-lc-ci")

app.synth()
75 changes: 75 additions & 0 deletions tests/ci/cdk/cdk/aws_lc_github_ci_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

from aws_cdk import core, aws_codebuild as codebuild, aws_iam as iam
from util.iam_policies import codebuild_batch_policy_in_json
from util.metadata import AWS_ACCOUNT, AWS_REGION, GITHUB_REPO_OWNER, GITHUB_REPO_NAME, LINUX_X86_ECR_REPO, \
LINUX_AARCH_ECR_REPO, WINDOWS_ECR_REPO
from util.yml_loader import YmlLoader


class AwsLcGitHubCIStack(core.Stack):
"""Define a stack used to batch execute AWS-LC tests in GitHub."""

def __init__(self,
scope: core.Construct,
id: str,
**kwargs) -> None:
super().__init__(scope, id, **kwargs)

# Define CodeBuild resource.
git_hub_source = codebuild.Source.git_hub(
owner=GITHUB_REPO_OWNER,
repo=GITHUB_REPO_NAME,
webhook=True,
webhook_filters=[
codebuild.FilterGroup.in_event_of(
codebuild.EventAction.PULL_REQUEST_CREATED,
codebuild.EventAction.PULL_REQUEST_UPDATED,
codebuild.EventAction.PULL_REQUEST_REOPENED)
],
clone_depth=1)

# Define a IAM role for this stack.
codebuild_batch_policy = iam.PolicyDocument.from_json(
codebuild_batch_policy_in_json([id])
)
inline_policies = {"codebuild_batch_policy": codebuild_batch_policy}
role = iam.Role(scope=self,
id="{}-role".format(id),
assumed_by=iam.ServicePrincipal("codebuild.amazonaws.com"),
inline_policies=inline_policies,
managed_policies=[
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonEC2ContainerRegistryReadOnly")
])

# Create build spec.
placeholder_map = {"AWS_ACCOUNT_ID_PLACEHOLDER": AWS_ACCOUNT, "AWS_REGION_PLACEHOLDER": AWS_REGION,
"ECR_REPO_X86_PLACEHOLDER": LINUX_X86_ECR_REPO,
"ECR_REPO_AARCH_PLACEHOLDER": LINUX_AARCH_ECR_REPO,
"ECR_REPO_WINDOWS_PLACEHOLDER": WINDOWS_ECR_REPO}
build_spec_content = YmlLoader.load("./cdk/codebuild/github_build_omnibus.yaml", placeholder_map)

# Define CodeBuild.
project = codebuild.Project(
scope=self,
id=id,
project_name=id,
source=git_hub_source,
role=role,
timeout=core.Duration.minutes(120),
environment=codebuild.BuildEnvironment(compute_type=codebuild.ComputeType.SMALL,
privileged=False,
build_image=codebuild.LinuxBuildImage.STANDARD_4_0),
build_spec=codebuild.BuildSpec.from_object(build_spec_content))

# TODO: add build type BUILD_BATCH when CFN finishes the feature release. See CryptoAlg-575.

# Add 'BuildBatchConfig' property, which is not supported in CDK.
# CDK raw overrides: https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html#cfn_layer_raw
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html#aws-resource-codebuild-project-properties
cfn_build = project.node.default_child
cfn_build.add_override("Properties.BuildBatchConfig", {
"ServiceRole": role.role_arn,
"TimeoutInMins": 120
})
Loading