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

feat: Support self-signed certificates #67

Merged
merged 4 commits into from Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
129 changes: 122 additions & 7 deletions API.md
Expand Up @@ -68,6 +68,7 @@ new CodeBuildImageBuilder(scope: Construct, id: string, props: CodeBuildImageBui
| **Name** | **Description** |
| --- | --- |
| <code><a href="#@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.toString">toString</a></code> | Returns a string representation of this construct. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addExtraCertificates">addExtraCertificates</a></code> | Add extra trusted certificates. This helps deal with self-signed certificates for GitHub Enterprise Server. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addFiles">addFiles</a></code> | Uploads a folder to the build server at a given folder name. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addPolicyStatement">addPolicyStatement</a></code> | Add a policy statement to the builder to access resources required to the image build. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addPostBuildCommand">addPostBuildCommand</a></code> | Adds a command that runs after `docker build` and `docker push`. |
Expand All @@ -85,6 +86,24 @@ public toString(): string

Returns a string representation of this construct.

##### `addExtraCertificates` <a name="addExtraCertificates" id="@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addExtraCertificates"></a>

```typescript
public addExtraCertificates(path: string): void
```

Add extra trusted certificates. This helps deal with self-signed certificates for GitHub Enterprise Server.

All first party Dockerfiles support this. Others may not.

###### `path`<sup>Required</sup> <a name="path" id="@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addExtraCertificates.parameter.path"></a>

- *Type:* string

path to directory containing a file called certs.pem containing all the required certificates.

---

##### `addFiles` <a name="addFiles" id="@cloudsnorkel/cdk-github-runners.CodeBuildImageBuilder.addFiles"></a>

```typescript
Expand Down Expand Up @@ -814,20 +833,20 @@ It creates a webhook, secrets, and a step function to orchestrate all runs. Secr
By default, this will create a runner provider of each available type with the defaults. This is good enough for the initial setup stage when you just want to get GitHub integration working.

```typescript
new GitHubRunners(stack, 'runners', {});
new GitHubRunners(this, 'runners');
```

Usually you'd want to configure the runner providers so the runners can run in a certain VPC or have certain permissions.

```typescript
const vpc = ec2.Vpc.fromLookup(stack, 'vpc', { vpcId: 'vpc-1234567' });
const runnerSg = new ec2.SecurityGroup(stack, 'runner security group', { vpc: vpc });
const dbSg = ec2.SecurityGroup.fromSecurityGroupId(stack, 'database security group', 'sg-1234567');
const bucket = new s3.Bucket(stack, 'runner bucket');
const vpc = ec2.Vpc.fromLookup(this, 'vpc', { vpcId: 'vpc-1234567' });
const runnerSg = new ec2.SecurityGroup(this, 'runner security group', { vpc: vpc });
const dbSg = ec2.SecurityGroup.fromSecurityGroupId(this, 'database security group', 'sg-1234567');
const bucket = new s3.Bucket(this, 'runner bucket');

// create a custom CodeBuild provider
const myProvider = new CodeBuildRunner(
stack, 'codebuild runner',
this, 'codebuild runner',
{
label: 'my-codebuild',
vpc: vpc,
Expand All @@ -840,7 +859,7 @@ dbSg.connections.allowFrom(runnerSg, ec2.Port.tcp(3306), 'allow runners to conne

// create the runner infrastructure
new GitHubRunners(
stack,
this,
'runners',
{
providers: [myProvider],
Expand Down Expand Up @@ -1962,7 +1981,61 @@ const gitHubRunnersProps: GitHubRunnersProps = { ... }

| **Name** | **Type** | **Description** |
| --- | --- | --- |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.allowPublicSubnet">allowPublicSubnet</a></code> | <code>boolean</code> | Allow management functions to run in public subnets. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.extraCertificates">extraCertificates</a></code> | <code>string</code> | Path to a directory containing a file named certs.pem containing any additional certificates required to trust GitHub Enterprise Server. Use this when GitHub Enterprise Server certificates are self-signed. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.providers">providers</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.IRunnerProvider">IRunnerProvider</a>[]</code> | List of runner providers to use. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.securityGroup">securityGroup</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup</code> | Security group attached to all management functions. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | VPC used for all management functions. |
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpcSubnets">vpcSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | VPC subnets used for all management functions. |

---

##### `allowPublicSubnet`<sup>Optional</sup> <a name="allowPublicSubnet" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.allowPublicSubnet"></a>

```typescript
public readonly allowPublicSubnet: boolean;
```

- *Type:* boolean
- *Default:* false

Allow management functions to run in public subnets.

Lambda Functions in a public subnet can NOT access the internet.

---

##### `extraCertificates`<sup>Optional</sup> <a name="extraCertificates" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.extraCertificates"></a>

```typescript
public readonly extraCertificates: string;
```

- *Type:* string

Path to a directory containing a file named certs.pem containing any additional certificates required to trust GitHub Enterprise Server. Use this when GitHub Enterprise Server certificates are self-signed.

You may also want to use custom images for your runner providers that contain the same certificates. See {@link CodeBuildImageBuilder.addCertificates}.

```typescript
const imageBuilder = new CodeBuildImageBuilder(this, 'Image Builder with Certs', {
dockerfilePath: CodeBuildRunner.LINUX_X64_DOCKERFILE_PATH,
});
imageBuilder.addExtraCertificates('path-to-my-extra-certs-folder');

const provider = new CodeBuildRunner(this, 'CodeBuild', {
imageBuilder: imageBuilder,
});

new GitHubRunners(
this,
'runners',
{
providers: [provider],
extraCertificates: 'path-to-my-extra-certs-folder',
}
);
```

---

Expand All @@ -1981,6 +2054,48 @@ At least one provider is required. Provider will be selected when its label matc

---

##### `securityGroup`<sup>Optional</sup> <a name="securityGroup" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.securityGroup"></a>

```typescript
public readonly securityGroup: ISecurityGroup;
```

- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup

Security group attached to all management functions.

Use this with to provide access to GitHub Enterprise Server hosted inside a VPC.

---

##### `vpc`<sup>Optional</sup> <a name="vpc" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc"></a>

```typescript
public readonly vpc: IVpc;
```

- *Type:* aws-cdk-lib.aws_ec2.IVpc

VPC used for all management functions.

Use this with GitHub Enterprise Server hosted that's inaccessible from outside the VPC.

---

##### `vpcSubnets`<sup>Optional</sup> <a name="vpcSubnets" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpcSubnets"></a>

```typescript
public readonly vpcSubnets: SubnetSelection;
```

- *Type:* aws-cdk-lib.aws_ec2.SubnetSelection

VPC subnets used for all management functions.

Use this with GitHub Enterprise Server hosted that's inaccessible from outside the VPC.

---

### LambdaRunnerProps <a name="LambdaRunnerProps" id="@cloudsnorkel/cdk-github-runners.LambdaRunnerProps"></a>

#### Initializer <a name="Initializer" id="@cloudsnorkel/cdk-github-runners.LambdaRunnerProps.Initializer"></a>
Expand Down
6 changes: 5 additions & 1 deletion src/providers/docker-images/codebuild/linux-arm64/Dockerfile
Expand Up @@ -6,10 +6,14 @@ RUN addgroup runner && adduser --system --disabled-password --home /home/runner

# add dependencies and sudo
ARG EXTRA_PACKAGES=""
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip iptables software-properties-common $EXTRA_PACKAGES && \
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip iptables software-properties-common ca-certificates $EXTRA_PACKAGES && \
usermod -aG sudo runner && \
echo "%sudo ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /usr/local/share/ca-certificates/github-enterprise-server.crt; update-ca-certificates; else echo no self-signed certificates; fi

# add latest git
RUN add-apt-repository ppa:git-core/ppa && apt update && apt-get install -y git

Expand Down
6 changes: 5 additions & 1 deletion src/providers/docker-images/codebuild/linux-x64/Dockerfile
Expand Up @@ -6,10 +6,14 @@ RUN addgroup runner && adduser --system --disabled-password --home /home/runner

# add dependencies and sudo
ARG EXTRA_PACKAGES=""
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip iptables software-properties-common $EXTRA_PACKAGES && \
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip iptables software-properties-common ca-certificates $EXTRA_PACKAGES && \
usermod -aG sudo runner && \
echo "%sudo ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /usr/local/share/ca-certificates/github-enterprise-server.crt; update-ca-certificates; else echo no self-signed certificates; fi

# add latest git
RUN add-apt-repository ppa:git-core/ppa && apt update && apt-get install -y git

Expand Down
6 changes: 5 additions & 1 deletion src/providers/docker-images/fargate/linux-arm64/Dockerfile
Expand Up @@ -6,10 +6,14 @@ RUN addgroup runner && adduser --system --disabled-password --home /home/runner

# add dependencies and sudo
ARG EXTRA_PACKAGES=""
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip software-properties-common $EXTRA_PACKAGES && \
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip software-properties-common ca-certificates $EXTRA_PACKAGES && \
usermod -aG sudo runner && \
echo "%sudo ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /usr/local/share/ca-certificates/github-enterprise-server.crt; update-ca-certificates; else echo no self-signed certificates; fi

# add latest git
RUN add-apt-repository ppa:git-core/ppa && apt update && apt-get install -y git

Expand Down
6 changes: 5 additions & 1 deletion src/providers/docker-images/fargate/linux-x64/Dockerfile
Expand Up @@ -6,10 +6,14 @@ RUN addgroup runner && adduser --system --disabled-password --home /home/runner

# add dependencies and sudo
ARG EXTRA_PACKAGES=""
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip software-properties-common $EXTRA_PACKAGES && \
RUN apt-get update && apt-get upgrade -y && apt-get install -y curl sudo jq bash zip unzip software-properties-common ca-certificates $EXTRA_PACKAGES && \
usermod -aG sudo runner && \
echo "%sudo ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /usr/local/share/ca-certificates/github-enterprise-server.crt; update-ca-certificates; else echo no self-signed certificates; fi

# add latest git
RUN add-apt-repository ppa:git-core/ppa && apt update && apt-get install -y git

Expand Down
4 changes: 4 additions & 0 deletions src/providers/docker-images/lambda/linux-arm64/Dockerfile
Expand Up @@ -5,6 +5,10 @@ FROM $BASE_IMAGE

WORKDIR /runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /etc/pki/ca-trust/source/anchors/ghe.crt; update-ca-trust; else echo no self-signed certificates; fi

# add dependencies
ARG EXTRA_PACKAGES=""
RUN yum update -y && yum install -y jq tar gzip bzip2 which binutils git zip unzip $EXTRA_PACKAGES
Expand Down
4 changes: 4 additions & 0 deletions src/providers/docker-images/lambda/linux-x64/Dockerfile
Expand Up @@ -5,6 +5,10 @@ FROM $BASE_IMAGE

WORKDIR /runner

# install extra certificates
COPY extra_certs/. /tmp/certs/
RUN if [ -f /tmp/certs/certs.pem ]; then cp /tmp/certs/certs.pem /etc/pki/ca-trust/source/anchors/ghe.crt; update-ca-trust; else echo no self-signed certificates; fi

# add dependencies
ARG EXTRA_PACKAGES=""
RUN yum update -y && yum install -y jq tar gzip bzip2 which binutils git zip unzip $EXTRA_PACKAGES
Expand Down
17 changes: 16 additions & 1 deletion src/providers/image-builders/codebuild.ts
Expand Up @@ -209,7 +209,7 @@ export class CodeBuildImageBuilder extends Construct implements IImageBuilder {

const asset = new s3_assets.Asset(this, destName, { path: sourcePath });
this.secondaryAssets.set(destName, asset);
this.preBuild.push(`ln -s "$CODEBUILD_SRC_DIR_${destName}" "${destName}"`);
this.preBuild.push(`rm -rf "${destName}" && cp -r "$CODEBUILD_SRC_DIR_${destName}" "${destName}"`); // symlinks don't work with docker
}

/**
Expand Down Expand Up @@ -261,6 +261,20 @@ export class CodeBuildImageBuilder extends Construct implements IImageBuilder {
this.policyStatements.push(statement);
}

/**
* Add extra trusted certificates. This helps deal with self-signed certificates for GitHub Enterprise Server.
*
* All first party Dockerfiles support this. Others may not.
*
* @param path path to directory containing a file called certs.pem containing all the required certificates
*/
public addExtraCertificates(path: string) {
if (this.boundImage) {
throw new Error('Image is already bound. Use this method before passing the builder to a runner provider.');
}
this.addFiles(path, 'extra_certs');
}

/**
* Called by IRunnerProvider to finalize settings and create the image builder.
*/
Expand Down Expand Up @@ -378,6 +392,7 @@ export class CodeBuildImageBuilder extends Construct implements IImageBuilder {
phases: {
pre_build: {
commands: this.preBuild.concat([
'mkdir -p extra_certs',
'$(aws ecr get-login --no-include-email --region "$AWS_DEFAULT_REGION")',
]),
},
Expand Down