Skip to content

Commit

Permalink
feat: use SSM Parameter Store to store secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
Stijn Seghers committed Apr 23, 2021
1 parent 797fb7d commit 1252ffc
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 125 deletions.
24 changes: 0 additions & 24 deletions modules/runners/encrypt.tf

This file was deleted.

16 changes: 8 additions & 8 deletions modules/runners/lambdas/runners/src/lambda.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { scaleUp } from './scale-runners/scale-up';
import { scaleDown } from './scale-runners/scale-down';
import { scaleUp as scaleUp_ } from './scale-runners/scale-up';
import { scaleDown as scaleDown_ } from './scale-runners/scale-down';
import { SQSEvent, ScheduledEvent, Context } from 'aws-lambda';

module.exports.scaleUp = async (event: SQSEvent, context: Context, callback: any) => {
export async function scaleUp(event: SQSEvent, context: Context, callback: any) {
console.dir(event, { depth: 5 });
try {
for (const e of event.Records) {
await scaleUp(e.eventSource, JSON.parse(e.body));
await scaleUp_(e.eventSource, JSON.parse(e.body));
}
return callback(null);
} catch (e) {
console.error(e);
return callback('Failed handling SQS event');
}
};
}

module.exports.scaleDown = async (event: ScheduledEvent, context: Context, callback: any) => {
export async function scaleDown(event: ScheduledEvent, context: Context, callback: any) {
try {
scaleDown();
scaleDown_();
return callback(null);
} catch (e) {
console.error(e);
return callback('Failed');
}
};
}
32 changes: 17 additions & 15 deletions modules/runners/lambdas/runners/src/scale-runners/gh-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { request } from '@octokit/request';
import { createAppAuth } from '@octokit/auth-app';
import { Authentication, StrategyOptions } from '@octokit/auth-app/dist-types/types';
import { OctokitOptions } from '@octokit/core/dist-types/types';
import { decrypt } from './kms';
import * as ssm from './ssm';

export async function createOctoClient(token: string, ghesApiUrl = ''): Promise<Octokit> {
const ocktokitOptions: OctokitOptions = {
Expand All @@ -21,25 +21,27 @@ export async function createGithubAuth(
authType: 'app' | 'installation',
ghesApiUrl = '',
): Promise<Authentication> {
const clientSecret = await decrypt(
process.env.GITHUB_APP_CLIENT_SECRET as string,
process.env.KMS_KEY_ID as string,
process.env.ENVIRONMENT as string,
const privateKeyBase64 = await ssm.fetch_parameter(
process.env.GITHUB_APP_KEY_BASE64_PARAMETER_NAME as string
);
const privateKeyBase64 = await decrypt(
process.env.GITHUB_APP_KEY_BASE64 as string,
process.env.KMS_KEY_ID as string,
process.env.ENVIRONMENT as string,
const appIdString = await ssm.fetch_parameter(
process.env.GITHUB_APP_ID_PARAMETER_NAME as string
);

if (clientSecret === undefined || privateKeyBase64 === undefined) {
throw Error('Cannot decrypt.');
const clientId = await ssm.fetch_parameter(
process.env.GITHUB_APP_CLIENT_ID_PARAMETER_NAME as string
);
const clientSecret = await ssm.fetch_parameter(
process.env.GITHUB_APP_CLIENT_SECRET_PARAMETER_NAME as string
);
if (privateKeyBase64 === undefined
|| appIdString === undefined
|| clientId === undefined
|| clientSecret === undefined) {
throw Error('Cannot decrypt GitHub App parameters.');
}

const privateKey = Buffer.from(privateKeyBase64, 'base64').toString();

const appId: number = parseInt(process.env.GITHUB_APP_ID as string);
const clientId = process.env.GITHUB_APP_CLIENT_ID as string;
const appId = parseInt(appIdString);

const authOptions: StrategyOptions = {
appId,
Expand Down
25 changes: 0 additions & 25 deletions modules/runners/lambdas/runners/src/scale-runners/kms/index.ts

This file was deleted.

15 changes: 15 additions & 0 deletions modules/runners/lambdas/runners/src/scale-runners/ssm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import AWS from 'aws-sdk';

AWS.config.update({
region: process.env.AWS_REGION,
});

const ssm = new AWS.SSM({ apiVersion: '2014-11-06' });

export async function fetch_parameter(name: string): Promise<string | undefined> {
const data = await ssm.getParameter({
Name: name,
WithDecryption: true,
}).promise();
return data.Parameter?.Value;
}
6 changes: 1 addition & 5 deletions modules/runners/policies/instance-ssm-parameters-policy.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ssm:DeleteParameter"],
"Resource": "${arn_ssm_parameters}"
},
{
"Effect": "Allow",
"Action": [
"ssm:DeleteParameter",
"ssm:GetParameters",
"ssm:GetParameter"
],
Expand Down
35 changes: 18 additions & 17 deletions modules/runners/scale-down.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ resource "aws_kms_grant" "scale_down" {
key_id = var.encryption.kms_key_id
grantee_principal = aws_iam_role.scale_down.arn
operations = ["Decrypt"]

constraints {
encryption_context_equals = {
Environment = var.environment
}
}
}

resource "aws_lambda_function" "scale_down" {
Expand All @@ -27,16 +21,15 @@ resource "aws_lambda_function" "scale_down" {

environment {
variables = {
ENVIRONMENT = var.environment
KMS_KEY_ID = var.encryption.kms_key_id
ENABLE_ORGANIZATION_RUNNERS = var.enable_organization_runners
MINIMUM_RUNNING_TIME_IN_MINUTES = var.minimum_running_time_in_minutes
GITHUB_APP_KEY_BASE64 = local.github_app_key_base64
GITHUB_APP_ID = var.github_app.id
GITHUB_APP_CLIENT_ID = var.github_app.client_id
GITHUB_APP_CLIENT_SECRET = local.github_app_client_secret
SCALE_DOWN_CONFIG = jsonencode(var.idle_config)
GHES_URL = var.ghes_url
ENVIRONMENT = var.environment
ENABLE_ORGANIZATION_RUNNERS = var.enable_organization_runners
MINIMUM_RUNNING_TIME_IN_MINUTES = var.minimum_running_time_in_minutes
GITHUB_APP_KEY_BASE64_PARAMETER_NAME = var.github_app.key_base64_parameter_name
GITHUB_APP_ID_PARAMETER_NAME = var.github_app.id_parameter_name
GITHUB_APP_CLIENT_ID_PARAMETER_NAME = var.github_app.client_id_parameter_name
GITHUB_APP_CLIENT_SECRET_PARAMETER_NAME = var.github_app.client_secret_parameter_name
SCALE_DOWN_CONFIG = jsonencode(var.idle_config)
GHES_URL = var.ghes_url
}
}

Expand Down Expand Up @@ -88,6 +81,14 @@ resource "aws_iam_role_policy" "scale_down" {
policy = templatefile("${path.module}/policies/lambda-scale-down.json", {})
}

resource "aws_iam_role_policy" "scale_down_ssm_parameters" {
name = "${var.environment}-lambda-scale-down-ssm-parameters"
role = aws_iam_role.scale_down.name
policy = templatefile("${path.module}/policies/instance-ssm-parameters-policy.json", {
arn_ssm_parameters = "arn:aws:ssm:${var.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/${var.environment}-*"
})
}

resource "aws_iam_role_policy" "scale_down_logging" {
name = "${var.environment}-lambda-logging"
role = aws_iam_role.scale_down.name
Expand All @@ -100,4 +101,4 @@ resource "aws_iam_role_policy_attachment" "scale_down_vpc_execution_role" {
count = length(var.lambda_subnet_ids) > 0 ? 1 : 0
role = aws_iam_role.scale_down.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}
}
41 changes: 21 additions & 20 deletions modules/runners/scale-up.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ resource "aws_kms_grant" "scale_up" {
key_id = var.encryption.kms_key_id
grantee_principal = aws_iam_role.scale_up.arn
operations = ["Decrypt"]

constraints {
encryption_context_equals = {
Environment = var.environment
}
}
}

resource "aws_lambda_function" "scale_up" {
Expand All @@ -28,20 +22,19 @@ resource "aws_lambda_function" "scale_up" {

environment {
variables = {
ENABLE_ORGANIZATION_RUNNERS = var.enable_organization_runners
ENVIRONMENT = var.environment
GHES_URL = var.ghes_url
GITHUB_APP_CLIENT_ID = var.github_app.client_id
GITHUB_APP_CLIENT_SECRET = local.github_app_client_secret
GITHUB_APP_ID = var.github_app.id
GITHUB_APP_KEY_BASE64 = local.github_app_key_base64
KMS_KEY_ID = var.encryption.kms_key_id
RUNNER_EXTRA_LABELS = var.runner_extra_labels
RUNNER_GROUP_NAME = var.runner_group_name
RUNNERS_MAXIMUM_COUNT = var.runners_maximum_count
LAUNCH_TEMPLATE_NAME = aws_launch_template.runner.name
LAUNCH_TEMPLATE_VERSION = aws_launch_template.runner.latest_version
SUBNET_IDS = join(",", var.subnet_ids)
ENABLE_ORGANIZATION_RUNNERS = var.enable_organization_runners
ENVIRONMENT = var.environment
GHES_URL = var.ghes_url
GITHUB_APP_KEY_BASE64_PARAMETER_NAME = var.github_app.key_base64_parameter_name
GITHUB_APP_ID_PARAMETER_NAME = var.github_app.id_parameter_name
GITHUB_APP_CLIENT_ID_PARAMETER_NAME = var.github_app.client_id_parameter_name
GITHUB_APP_CLIENT_SECRET_PARAMETER_NAME = var.github_app.client_secret_parameter_name
RUNNER_EXTRA_LABELS = var.runner_extra_labels
RUNNER_GROUP_NAME = var.runner_group_name
RUNNERS_MAXIMUM_COUNT = var.runners_maximum_count
LAUNCH_TEMPLATE_NAME = aws_launch_template.runner.name
LAUNCH_TEMPLATE_VERSION = aws_launch_template.runner.latest_version
SUBNET_IDS = join(",", var.subnet_ids)
}
}

Expand Down Expand Up @@ -91,6 +84,14 @@ resource "aws_iam_role_policy" "scale_up" {
})
}

resource "aws_iam_role_policy" "scale_up_ssm_parameters" {
name = "${var.environment}-lambda-scale-up-ssm-parameters"
role = aws_iam_role.scale_up.name
policy = templatefile("${path.module}/policies/instance-ssm-parameters-policy.json", {
arn_ssm_parameters = "arn:aws:ssm:${var.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/${var.environment}-*"
})
}

resource "aws_iam_role_policy" "scale_up_logging" {
name = "${var.environment}-lambda-logging"
role = aws_iam_role.scale_up.name
Expand Down
10 changes: 5 additions & 5 deletions modules/runners/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ variable "enable_organization_runners" {
}

variable "github_app" {
description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)."
description = "GitHub App parameters. See your GitHub App. All values are expected to be valid SSM Parameter names, referring to existing SSM Parameters. Ensure the private key is the base64-encoding of the `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem` itself)."
type = object({
key_base64 = string
id = string
client_id = string
client_secret = string
key_base64_parameter_name = string
id_parameter_name = string
client_id_parameter_name = string
client_secret_parameter_name = string
})
}

Expand Down
12 changes: 6 additions & 6 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ variable "enable_organization_runners" {
}

variable "github_app" {
description = "GitHub app parameters, see your github app. Ensure the key is the base64-encoded `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem`)."
description = "GitHub App parameters. See your GitHub App. All values except the webhook secret are expected to be valid SSM Parameter names, referring to existing SSM Parameters. Ensure the private key is the base64-encoding of the `.pem` file (the output of `base64 app.private-key.pem`, not the content of `private-key.pem` itself)."
type = object({
key_base64 = string
id = string
client_id = string
client_secret = string
webhook_secret = string
key_base64_parameter_name = string
id_parameter_name = string
client_id_parameter_name = string
client_secret_parameter_name = string
webhook_secret = string
})
}

Expand Down

0 comments on commit 1252ffc

Please sign in to comment.