Skip to content

Commit 4aa3693

Browse files
authored
#34 - encrypt secrets via KMS (#37)
* #34 - encrypt secrets via KMS * Upgrade javascripts deps * Terraform docs for readme
1 parent 88bc451 commit 4aa3693

File tree

28 files changed

+2127
-1693
lines changed

28 files changed

+2127
-1693
lines changed

README.md

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ This [Terraform](https://www.terraform.io/) modules create the required infra st
1010
- [Setup GitHub App (part 1)](#setup-github-app-part-1)
1111
- [Setup terraform module](#setup-terraform-module)
1212
- [Setup GitHub App (part 2)](#setup-github-app-part-2)
13+
- [Encryption](#encryption)
14+
- [Encrypted via a module managed KMS key (default)](#encrypted-via-a-module-managed-kms-key-default)
15+
- [Encrypted via a provided KMS key](#encrypted-via-a-provided-kms-key)
16+
- [No encryption](#no-encryption)
1317
- [Examples](#examples)
1418
- [Sub modules](#sub-modules)
1519
- [Requirements](#requirements)
@@ -42,6 +46,8 @@ Scaling down the runners is at the moment brute-forced, every configurable amoun
4246

4347
Downloading the GitHub Action Runner distribution can be occasionally slow (more than 10 minutes). Therefore a lambda is introduced that synchronizes the action runner binary from GitHub to an S3 bucket. The EC2 instance will fetch the distribution from the S3 bucket instead of the internet.
4448

49+
Secrets and private keys which are passed the Lambda's as environment variables are encrypted by default by a KMS key managed by the module. Alternatively you can pass your own KMS key. Encryption via KMS can be complete disabled by setting `encrypt_secrets` to `false`.
50+
4551
![Architecture](docs/component-overview.svg)
4652

4753
Permission are managed on several places. Below the most important ones. For details check the Terraform sources.
@@ -165,6 +171,37 @@ Go back to the GitHub App and update the following settings.
165171

166172
You are now ready to run action workloads on self hosted runner, remember builds will fail if there is no (offline) runner available with matching labels.
167173

174+
### Encryption
175+
176+
The module support 3 scenario's to manage environment secrets and private key of the Lambda functions.
177+
178+
#### Encrypted via a module managed KMS key (default)
179+
180+
This is the default, no additional configuration is required.
181+
182+
#### Encrypted via a provided KMS key
183+
184+
You have to create an configure you KMS key. The module will use the context with key: `Environment` and value `var.environment` as encryption context.
185+
186+
```HCL
187+
resource "aws_kms_key" "github" {
188+
is_enabled = true
189+
}
190+
191+
module "runners" {
192+
193+
...
194+
manage_kms_key = false
195+
kms_key_id = aws_kms_key.github.key_id
196+
...
197+
198+
```
199+
200+
#### No encryption
201+
202+
Not advised but you can disable the encryption as by setting the variable `encrypt_secrets` to `false`.
203+
204+
168205
## Examples
169206

170207
Examples are located in the [examples](./examples) directory. The following examples are provided:
@@ -188,52 +225,54 @@ The following sub modules are optional and are provided as example or utility:
188225
- _[setup-iam-permissions](./modules/setup-iam-permissions/README.md)_ - Example module to setup permission boundaries
189226

190227
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
191-
192228
## Requirements
193229

194230
No requirements.
195231

196232
## Providers
197233

198-
| Name | Version |
199-
| ------ | ------- |
200-
| aws | n/a |
201-
| random | n/a |
234+
| Name | Version |
235+
|------|---------|
236+
| aws | n/a |
237+
| random | n/a |
202238

203239
## Inputs
204240

205-
| Name | Description | Type | Default | Required |
206-
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | :------: |
207-
| aws_region | AWS region. | `string` | n/a | yes |
208-
| enable_organization_runners | n/a | `bool` | n/a | yes |
209-
| environment | A name that identifies the environment, used as prefix and for tagging. | `string` | n/a | yes |
210-
| github_app | GitHub app parameters, see your github aapp. Ensure the key is base64 encoded. | <pre>object({<br> key_base64 = string<br> id = string<br> client_id = string<br> client_secret = string<br> webhook_secret = string<br> })</pre> | n/a | yes |
211-
| instance_profile_path | The path that will be added to the instance_profile, if not set the environment name will be used. | `string` | `null` | no |
212-
| minimum_running_time_in_minutes | The time an ec2 action runner should be running at minium before terminated if non busy. | `number` | `5` | no |
213-
| role_path | The path that will be added to role path for created roles, if not set the environment name will be used. | `string` | `null` | no |
214-
| role_permissions_boundary | Permissions boundary that will be added to the created roles. | `string` | `null` | no |
215-
| runner_as_root | Run the action runner under the root user. | `bool` | `false` | no |
216-
| runner_binaries_syncer_lambda_timeout | Time out of the binaries sync lambda in seconds. | `number` | `300` | no |
217-
| runner_binaries_syncer_lambda_zip | File location of the binaries sync lambda zip file. | `string` | `null` | no |
218-
| runner_extra_labels | Extra labels for the runners (GitHub). Separate each label by a comma | `string` | `""` | no |
219-
| runners_lambda_zip | File location of the lambda zip file for scaling runners. | `string` | `null` | no |
220-
| runners_maxiumum_count | The maxiumum number of runners tha will be created. | `number` | `3` | no |
221-
| runners_scale_down_lambda_timeout | Time out for the scale up lambda in seconds. | `number` | `60` | no |
222-
| runners_scale_up_lambda_timeout | Time out for the scale down lambda in seconds. | `number` | `60` | no |
223-
| scale_down_schedule_expression | Scheduler expression to check every x for scale down. | `string` | `"cron(*/5 * * * ? *)"` | no |
224-
| subnet_ids | List of subnets in which the action runners will be launched, the subnets needs to be subnets in the `vpc_id`. | `list(string)` | n/a | yes |
225-
| tags | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no |
226-
| vpc_id | The VPC for security groups of the action runners. | `string` | n/a | yes |
227-
| webhook_lambda_timeout | Time out of the webhook lambda in seconds. | `number` | `10` | no |
228-
| webhook_lambda_zip | File location of the wehbook lambda zip file. | `string` | `null` | no |
241+
| Name | Description | Type | Default | Required |
242+
|------|-------------|------|---------|:--------:|
243+
| aws\_region | AWS region. | `string` | n/a | yes |
244+
| enable\_organization\_runners | n/a | `bool` | n/a | yes |
245+
| encrypt\_secrets | Encrypt secret variables for lambda's such as secrets and private keys. | `bool` | `true` | no |
246+
| environment | A name that identifies the environment, used as prefix and for tagging. | `string` | n/a | yes |
247+
| github\_app | GitHub app parameters, see your github aapp. Ensure the key is base64 encoded. | <pre>object({<br> key_base64 = string<br> id = string<br> client_id = string<br> client_secret = string<br> webhook_secret = string<br> })</pre> | n/a | yes |
248+
| instance\_profile\_path | The path that will be added to the instance\_profile, if not set the environment name will be used. | `string` | `null` | no |
249+
| kms\_key\_id | Custom KMS key to encrypted lambda secrets, if not provided and `encrypt_secrets` = `true` a KMS key will be created by the module. Secrets will be encrypted with a context `Environment = var.environment`. | `string` | `null` | no |
250+
| manage\_kms\_key | Let the module manage the KMS key. | `bool` | `true` | no |
251+
| minimum\_running\_time\_in\_minutes | The time an ec2 action runner should be running at minium before terminated if non busy. | `number` | `5` | no |
252+
| role\_path | The path that will be added to role path for created roles, if not set the environment name will be used. | `string` | `null` | no |
253+
| role\_permissions\_boundary | Permissions boundary that will be added to the created roles. | `string` | `null` | no |
254+
| runner\_as\_root | Run the action runner under the root user. | `bool` | `false` | no |
255+
| runner\_binaries\_syncer\_lambda\_timeout | Time out of the binaries sync lambda in seconds. | `number` | `300` | no |
256+
| runner\_binaries\_syncer\_lambda\_zip | File location of the binaries sync lambda zip file. | `string` | `null` | no |
257+
| runner\_extra\_labels | Extra labels for the runners (GitHub). Separate each label by a comma | `string` | `""` | no |
258+
| runners\_lambda\_zip | File location of the lambda zip file for scaling runners. | `string` | `null` | no |
259+
| runners\_maxiumum\_count | The maxiumum number of runners tha will be created. | `number` | `3` | no |
260+
| runners\_scale\_down\_lambda\_timeout | Time out for the scale up lambda in seconds. | `number` | `60` | no |
261+
| runners\_scale\_up\_lambda\_timeout | Time out for the scale down lambda in seconds. | `number` | `60` | no |
262+
| scale\_down\_schedule\_expression | Scheduler expression to check every x for scale down. | `string` | `"cron(*/5 * * * ? *)"` | no |
263+
| subnet\_ids | List of subnets in which the action runners will be launched, the subnets needs to be subnets in the `vpc_id`. | `list(string)` | n/a | yes |
264+
| tags | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no |
265+
| vpc\_id | The VPC for security groups of the action runners. | `string` | n/a | yes |
266+
| webhook\_lambda\_timeout | Time out of the webhook lambda in seconds. | `number` | `10` | no |
267+
| webhook\_lambda\_zip | File location of the wehbook lambda zip file. | `string` | `null` | no |
229268

230269
## Outputs
231270

232-
| Name | Description |
233-
| --------------- | ----------- |
234-
| binaries_syncer | n/a |
235-
| runners | n/a |
236-
| webhook | n/a |
271+
| Name | Description |
272+
|------|-------------|
273+
| binaries\_syncer | n/a |
274+
| runners | n/a |
275+
| webhook | n/a |
237276

238277
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
239278

examples/default/main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ module "runners" {
3232
runners_lambda_zip = "lambdas-download/runners.zip"
3333
enable_organization_runners = false
3434
runner_extra_labels = "default,example"
35+
36+
# disable KMS and ecnryption
37+
# encrypt_secrets = false
3538
}
3639

3740

examples/permissions-boundary/main.tf

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,27 @@ data "terraform_remote_state" "iam" {
1515
}
1616
}
1717

18+
19+
resource "aws_kms_key" "github" {
20+
is_enabled = true
21+
}
22+
23+
resource "aws_kms_alias" "github" {
24+
name = "alias/github/action-runners"
25+
target_key_id = aws_kms_key.github.key_id
26+
}
27+
1828
module "runners" {
1929
source = "../../"
2030
providers = {
2131
aws = aws.terraform_role
2232
}
2333

24-
aws_region = local.aws_region
25-
vpc_id = module.vpc.vpc_id
26-
subnet_ids = module.vpc.private_subnets
34+
aws_region = local.aws_region
35+
vpc_id = module.vpc.vpc_id
36+
subnet_ids = module.vpc.private_subnets
37+
manage_kms_key = false
38+
kms_key_id = aws_kms_key.github.key_id
2739

2840
environment = local.environment
2941
tags = {

kms.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
locals {
2+
kms_key_id = var.kms_key_id == null && var.encrypt_secrets ? aws_kms_key.default[0].key_id : var.kms_key_id
3+
}
4+
5+
resource "aws_kms_key" "default" {
6+
count = var.manage_kms_key && var.encrypt_secrets ? 1 : 0
7+
is_enabled = true
8+
tags = local.tags
9+
}
10+
11+
resource "aws_kms_alias" "default" {
12+
count = var.manage_kms_key && var.encrypt_secrets ? 1 : 0
13+
name = "alias/github-action-runners/${var.environment}"
14+
target_key_id = aws_kms_key.default[0].key_id
15+
}

main.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ module "webhook" {
2929
aws_region = var.aws_region
3030
environment = var.environment
3131
tags = local.tags
32+
encryption = {
33+
kms_key_id = local.kms_key_id
34+
encrypt = var.encrypt_secrets
35+
}
3236

3337
sqs_build_queue = aws_sqs_queue.queued_builds
3438
github_app_webhook_secret = var.github_app.webhook_secret
@@ -48,6 +52,10 @@ module "runners" {
4852
subnet_ids = var.subnet_ids
4953
environment = var.environment
5054
tags = local.tags
55+
encryption = {
56+
kms_key_id = local.kms_key_id
57+
encrypt = var.encrypt_secrets
58+
}
5159

5260
s3_bucket_runner_binaries = module.runner_binaries.bucket
5361
s3_location_runner_binaries = local.s3_action_runner_url

modules/download-lambda/README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ No requirements.
3232
## Providers
3333

3434
| Name | Version |
35-
| ---- | ------- |
36-
| null | n/a |
35+
|------|---------|
36+
| null | n/a |
3737

3838
## Inputs
3939

40-
| Name | Description | Type | Default | Required |
41-
| ------- | ------------------------------------- | --------------------------------------------------------------------------- | ------- | :------: |
42-
| lambdas | Name and tag for lambdas to download. | <pre>list(object({<br> name = string<br> tag = string<br> }))</pre> | n/a | yes |
40+
| Name | Description | Type | Default | Required |
41+
|------|-------------|------|---------|:--------:|
42+
| lambdas | Name and tag for lambdas to download. | <pre>list(object({<br> name = string<br> tag = string<br> }))</pre> | n/a | yes |
4343

4444
## Outputs
4545

46-
| Name | Description |
47-
| ----- | ----------- |
48-
| files | n/a |
46+
| Name | Description |
47+
|------|-------------|
48+
| files | n/a |
4949

5050
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
5151

0 commit comments

Comments
 (0)