Skip to content

Commit

Permalink
feat!: Organise SSM paramamters by path (#2569)
Browse files Browse the repository at this point in the history
Migration is only required when using pre-build AMI with your tailored start-runner script. Before all parameters were based on convetion. We have update them to be predictable with still similar conventions as default.

We set the tag ghr:ssm_config_path as EC2 instance tag to the path used for the configuration. In the config path we store the same values as before (run_as, enable_cloudwatch, agent_mode). The tokens are stored in a separate location which can be retrieved by looking up the value token_path in the config.

For a more details example check-out the following diffs:

Linux start script // TODO UPDATE AFTER MERGE
Windows start script // TODO UPDATE AFTER MERGE
  • Loading branch information
npalm committed Dec 28, 2022
1 parent 0823d47 commit b912bb8
Show file tree
Hide file tree
Showing 104 changed files with 1,535 additions and 2,064 deletions.
8 changes: 8 additions & 0 deletions .github/lint/tflint.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
aws_region = null
github_app = {
id = "0"
key_base64 = "0"
webhook_secret = "0"
}
subnet_ids = []
vpc_id = null
13 changes: 13 additions & 0 deletions .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
paths-ignore:
- "modules/*/lambdas/**"

permissions:
contents: read
pull-requests: write

env:
AWS_REGION: eu-west-1
jobs:
Expand Down Expand Up @@ -37,6 +41,14 @@ jobs:
continue-on-error: true
- name: validate terraform
run: terraform validate
- if: contains(matrix.terraform, '1.3.')
name: Setup TFLint
uses: terraform-linters/setup-tflint@v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- if: contains(matrix.terraform, '1.3.')
name: Run TFLint
run: tflint -f compact

verify_examples:
name: Verify examples
Expand Down Expand Up @@ -92,3 +104,4 @@ jobs:
continue-on-error: true
- name: validate terraform
run: terraform validate

4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.52.0
rev: v1.76.0
hooks:
- id: terraform_fmt
- id: terraform_tflint
- id: terraform_docs
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.3.0
hooks:
- id: check-merge-conflict
7 changes: 7 additions & 0 deletions .tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
config {
format = "compact"
module = true

varfile = [".github/lint/tflint.tfvars"]

}
41 changes: 32 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This [Terraform](https://www.terraform.io/) module creates the required infrastr
- [Motivation](#motivation)
- [Overview](#overview)
- [Major configuration options.](#major-configuration-options)
- [AWS SSM Parameters](#aws-ssm-parameters)
- [Usages](#usages)
- [Setup GitHub App (part 1)](#setup-github-app-part-1)
- [Setup terraform module](#setup-terraform-module)
Expand Down Expand Up @@ -91,6 +92,26 @@ To be able to support a number of use-cases the module has quite a lot of config
- Spot vs on-demand. The runners use either the EC2 spot or on-demand life cycle. Runners will be created via the AWS [CreateFleet API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateFleet.html). The module (scale up lambda) will request via the CreateFleet API to create instances in one of the subnets and of the specified instance types.
- ARM64 support via Graviton/Graviton2 instance-types. When using the default example or top-level module, specifying `instance_types` that match a Graviton/Graviton 2 (ARM64) architecture (e.g. a1, t4g or any 6th-gen `g` or `gd` type), you must also specify `runner_architecture = "arm64"` and the sub-modules will be automatically configured to provision with ARM64 AMIs and leverage GitHub's ARM64 action runner. See below for more details.

### AWS SSM Parameters

The module uses the AWS System Manager Parameter store to store configuration for the runners, registration tokens and secrets for the Lambda's. Via the variable `ssm_paths` paths for the parameters can be configured. The location of the configuration parameters is retrieved buy the runners via the instance tag `ghr:ssm_config_path`. The following default paths will be used.

| Path | Description |
| ----------- | ----------- |
| `ssm_paths.root`/`var.prefix`?/app/ | App secrets used by Lambda's |
| `ssm_paths.root`/`var.prefix`?/runners/config/`<name>` | Configuration parameters used by runner start script |
| `ssm_paths.root`/`var.prefix`?/runners/tokens/`<ec2-instance-id>` | Registration tokens for the runners generate by the scale-up lambda, consumed by the start script on the runner. |

Available configuration parameters:

| Parameter name | Description |
| ----------- | ----------- |
| `agent_mode` | Indicates if the agent is running in ephemeral mode or not. |
| `enable_cloudwatch` | Configuration for the cloudwatch agent to stream logging. |
| `run_as` | The user used for running the GitHub action runner agent. |
| `token_path` | The path where tokens are stored. |


## Usages

Examples are provided in [the example directory](examples/). Please ensure you have installed the following tools.
Expand Down Expand Up @@ -384,15 +405,16 @@ We welcome any improvement to the standard module to make the default as secure

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.14.1 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.15 |
| <a name="requirement_random"></a> [random](#requirement\_random) | ~> 3.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.15 |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
| <a name="provider_random"></a> [random](#provider\_random) | ~> 3.0 |

## Modules

Expand Down Expand Up @@ -459,7 +481,7 @@ We welcome any improvement to the standard module to make the default as secure
| <a name="input_lambda_architecture"></a> [lambda\_architecture](#input\_lambda\_architecture) | AWS Lambda architecture. Lambda functions using Graviton processors ('arm64') tend to have better price/performance than 'x86\_64' functions. | `string` | `"x86_64"` | no |
| <a name="input_lambda_principals"></a> [lambda\_principals](#input\_lambda\_principals) | (Optional) add extra principals to the role created for execution of the lambda, e.g. for local testing. | <pre>list(object({<br> type = string<br> identifiers = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_lambda_runtime"></a> [lambda\_runtime](#input\_lambda\_runtime) | AWS Lambda runtime. | `string` | `"nodejs16.x"` | no |
| <a name="input_lambda_s3_bucket"></a> [lambda\_s3\_bucket](#input\_lambda\_s3\_bucket) | S3 bucket from which to specify lambda functions. This is an alternative to providing local files directly. | `any` | `null` | no |
| <a name="input_lambda_s3_bucket"></a> [lambda\_s3\_bucket](#input\_lambda\_s3\_bucket) | S3 bucket from which to specify lambda functions. This is an alternative to providing local files directly. | `string` | `null` | no |
| <a name="input_lambda_security_group_ids"></a> [lambda\_security\_group\_ids](#input\_lambda\_security\_group\_ids) | List of security group IDs associated with the Lambda function. | `list(string)` | `[]` | no |
| <a name="input_lambda_subnet_ids"></a> [lambda\_subnet\_ids](#input\_lambda\_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)` | `[]` | no |
| <a name="input_log_level"></a> [log\_level](#input\_log\_level) | Logging level for lambda logging. Valid values are 'silly', 'trace', 'debug', 'info', 'warn', 'error', 'fatal'. | `string` | `"info"` | no |
Expand Down Expand Up @@ -498,25 +520,26 @@ We welcome any improvement to the standard module to make the default as secure
| <a name="input_runner_metadata_options"></a> [runner\_metadata\_options](#input\_runner\_metadata\_options) | Metadata options for the ec2 runner instances. By default, the module uses metadata tags for bootstrapping the runner, only disable `instance_metadata_tags` when using custom scripts for starting the runner. | `map(any)` | <pre>{<br> "http_endpoint": "enabled",<br> "http_put_response_hop_limit": 1,<br> "http_tokens": "optional",<br> "instance_metadata_tags": "enabled"<br>}</pre> | no |
| <a name="input_runner_os"></a> [runner\_os](#input\_runner\_os) | The EC2 Operating System type to use for action runner instances (linux,windows). | `string` | `"linux"` | no |
| <a name="input_runner_run_as"></a> [runner\_run\_as](#input\_runner\_run\_as) | Run the GitHub actions agent as user. | `string` | `"ec2-user"` | no |
| <a name="input_runners_lambda_s3_key"></a> [runners\_lambda\_s3\_key](#input\_runners\_lambda\_s3\_key) | S3 key for runners lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
| <a name="input_runners_lambda_s3_object_version"></a> [runners\_lambda\_s3\_object\_version](#input\_runners\_lambda\_s3\_object\_version) | S3 object version for runners lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |
| <a name="input_runners_lambda_s3_key"></a> [runners\_lambda\_s3\_key](#input\_runners\_lambda\_s3\_key) | S3 key for runners lambda function. Required if using S3 bucket to specify lambdas. | `string` | `null` | no |
| <a name="input_runners_lambda_s3_object_version"></a> [runners\_lambda\_s3\_object\_version](#input\_runners\_lambda\_s3\_object\_version) | S3 object version for runners lambda function. Useful if S3 versioning is enabled on source bucket. | `string` | `null` | no |
| <a name="input_runners_lambda_zip"></a> [runners\_lambda\_zip](#input\_runners\_lambda\_zip) | File location of the lambda zip file for scaling runners. | `string` | `null` | no |
| <a name="input_runners_maximum_count"></a> [runners\_maximum\_count](#input\_runners\_maximum\_count) | The maximum number of runners that will be created. | `number` | `3` | no |
| <a name="input_runners_scale_down_lambda_timeout"></a> [runners\_scale\_down\_lambda\_timeout](#input\_runners\_scale\_down\_lambda\_timeout) | Time out for the scale down lambda in seconds. | `number` | `60` | no |
| <a name="input_runners_scale_up_lambda_timeout"></a> [runners\_scale\_up\_lambda\_timeout](#input\_runners\_scale\_up\_lambda\_timeout) | Time out for the scale up lambda in seconds. | `number` | `30` | no |
| <a name="input_scale_down_schedule_expression"></a> [scale\_down\_schedule\_expression](#input\_scale\_down\_schedule\_expression) | Scheduler expression to check every x for scale down. | `string` | `"cron(*/5 * * * ? *)"` | no |
| <a name="input_scale_up_reserved_concurrent_executions"></a> [scale\_up\_reserved\_concurrent\_executions](#input\_scale\_up\_reserved\_concurrent\_executions) | Amount of reserved concurrent executions for the scale-up lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations. | `number` | `1` | no |
| <a name="input_ssm_paths"></a> [ssm\_paths](#input\_ssm\_paths) | The root path used in SSM to store configuration and secreets. | <pre>object({<br> root = string<br> use_prefix = bool<br> app = string<br> runners = string<br> })</pre> | <pre>{<br> "app": "app",<br> "root": "github-action-runners",<br> "runners": "runners",<br> "use_prefix": true<br>}</pre> | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_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 |
| <a name="input_syncer_lambda_s3_key"></a> [syncer\_lambda\_s3\_key](#input\_syncer\_lambda\_s3\_key) | S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
| <a name="input_syncer_lambda_s3_object_version"></a> [syncer\_lambda\_s3\_object\_version](#input\_syncer\_lambda\_s3\_object\_version) | S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |
| <a name="input_syncer_lambda_s3_key"></a> [syncer\_lambda\_s3\_key](#input\_syncer\_lambda\_s3\_key) | S3 key for syncer lambda function. Required if using S3 bucket to specify lambdas. | `string` | `null` | no |
| <a name="input_syncer_lambda_s3_object_version"></a> [syncer\_lambda\_s3\_object\_version](#input\_syncer\_lambda\_s3\_object\_version) | S3 object version for syncer lambda function. Useful if S3 versioning is enabled on source bucket. | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no |
| <a name="input_userdata_post_install"></a> [userdata\_post\_install](#input\_userdata\_post\_install) | Script to be ran after the GitHub Actions runner is installed on the EC2 instances | `string` | `""` | no |
| <a name="input_userdata_pre_install"></a> [userdata\_pre\_install](#input\_userdata\_pre\_install) | Script to be ran before the GitHub Actions runner is installed on the EC2 instances | `string` | `""` | no |
| <a name="input_userdata_template"></a> [userdata\_template](#input\_userdata\_template) | Alternative user-data template, replacing the default template. By providing your own user\_data you have to take care of installing all required software, including the action runner. Variables userdata\_pre/post\_install are ignored. | `string` | `null` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The VPC for security groups of the action runners. | `string` | n/a | yes |
| <a name="input_webhook_lambda_apigateway_access_log_settings"></a> [webhook\_lambda\_apigateway\_access\_log\_settings](#input\_webhook\_lambda\_apigateway\_access\_log\_settings) | n/a | <pre>object({<br> destination_arn = string<br> format = string<br> })</pre> | `null` | no |
| <a name="input_webhook_lambda_s3_key"></a> [webhook\_lambda\_s3\_key](#input\_webhook\_lambda\_s3\_key) | S3 key for webhook lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
| <a name="input_webhook_lambda_s3_object_version"></a> [webhook\_lambda\_s3\_object\_version](#input\_webhook\_lambda\_s3\_object\_version) | S3 object version for webhook lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |
| <a name="input_webhook_lambda_s3_key"></a> [webhook\_lambda\_s3\_key](#input\_webhook\_lambda\_s3\_key) | S3 key for webhook lambda function. Required if using S3 bucket to specify lambdas. | `string` | `null` | no |
| <a name="input_webhook_lambda_s3_object_version"></a> [webhook\_lambda\_s3\_object\_version](#input\_webhook\_lambda\_s3\_object\_version) | S3 object version for webhook lambda function. Useful if S3 versioning is enabled on source bucket. | `string` | `null` | no |
| <a name="input_webhook_lambda_timeout"></a> [webhook\_lambda\_timeout](#input\_webhook\_lambda\_timeout) | Time out of the webhook lambda in seconds. | `number` | `10` | no |
| <a name="input_webhook_lambda_zip"></a> [webhook\_lambda\_zip](#input\_webhook\_lambda\_zip) | File location of the webhook lambda zip file. | `string` | `null` | no |
| <a name="input_workflow_job_queue_configuration"></a> [workflow\_job\_queue\_configuration](#input\_workflow\_job\_queue\_configuration) | Configuration options for workflow job queue which is only applicable if the flag enable\_workflow\_job\_events\_queue is set to true. | <pre>object({<br> delay_seconds = number<br> visibility_timeout_seconds = number<br> message_retention_seconds = number<br> })</pre> | <pre>{<br> "delay_seconds": null,<br> "message_retention_seconds": null,<br> "visibility_timeout_seconds": null<br>}</pre> | no |
Expand Down
56 changes: 30 additions & 26 deletions examples/arm64/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions examples/arm64/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Steps for the full setup, such as creating a GitHub app can be found in the root
> Ensure you have set the version in `lambdas-download/main.tf` for running the example. The version needs to be set to a GitHub release version, see https://github.com/philips-labs/terraform-aws-github-runner/releases
```bash
cd lambdas-download
cd ../lambdas-download
terraform init
terraform apply
cd ..
terraform apply -var=module_version=<VERSION>
cd -
```

Before running Terraform, ensure the GitHub app is configured. See the [configuration details](https://github.com/philips-labs/terraform-aws-github-runner#usages) for more details.
Expand Down
3 changes: 3 additions & 0 deletions examples/arm64/lambdas-download/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
required_version = ">= 1"
}
Loading

0 comments on commit b912bb8

Please sign in to comment.