Skip to content

Commit

Permalink
feat: Support self-signed certificates (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
kichik committed Jun 30, 2022
1 parent dc902c8 commit db043b2
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 36 deletions.
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

0 comments on commit db043b2

Please sign in to comment.