You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/modules/internal/compute-provider-refactor.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@
8
8
9
9
The scale-up, scale-down, pool, job-retry, queue, SSM housekeeping, and GitHub registration workflows are not inherently EC2-specific. The legacy `runners` module combines that common control plane with EC2 launch templates, instance profiles, bootstrap parameters, log groups, IAM permissions, and Lambda environment variables. Adding another compute provider in that structure would require copying common behavior or adding provider conditionals throughout the module.
10
10
11
-
The refactor introduces a provider boundary so a future MicroVM or other backend can reuse the control plane. Only the policy statements, environment variables, and resources required by the selected compute provider should change.
11
+
The refactor introduces a provider boundary so MicroVM and other backends can reuse the control plane. Only the policy statements, environment variables, and resources required by the selected compute provider should change.
12
12
13
13
## Ownership model
14
14
@@ -25,11 +25,11 @@ The implementation is split into orchestration, provider-neutral control-plane c
25
25
|`compute-providers/<provider>/trust-policy`| Provider-specific default runner-role trust, merged with the optional caller-provided trust document before the common role is created. |
26
26
|`compute-providers/<provider>`| Provider-specific resources, permission requirements, and the IAM and environment-variable fragments consumed by the common control plane after the runner role is resolved. |
27
27
28
-
The EC2 provider owns the instance profile, launch template, security group, AMI and bootstrap parameters, runner log groups, EC2 policy statements, and EC2 Lambda environment variables. EC2 is the only implemented Terraform compute provider in this phase.
28
+
The EC2 provider owns the instance profile, launch template, security group, AMI and bootstrap parameters, runner log groups, EC2 policy statements, and EC2 Lambda environment variables. The MicroVM provider owns the Lambda MicroVM runtime configuration, execution-role policy, and MicroVM Lambda environment variables. Terraform does not manage MicroVM lifecycle resources directly; the runtime control plane creates and terminates MicroVM runners.
29
29
30
30
The modules below `runner-stack` are internal implementation boundaries, not standalone public modules. Callers opt into the experimental interface through `experimental.multi_runner_config_v2`; `multi-runner` calls `runner-stack`, which composes the internal modules. Their direct input and output contracts may change while v2 remains experimental.
31
31
32
-
`runner-stack` selects a compute provider from the single populated typed block under `compute_provider`. For example, `compute_provider = { ec2 = { ... } }` selects EC2; there is no separate `type` input that can disagree with the populated block. Exactly one provider block must be populated, and its presence must be known during planning because it determines the module graph. Native input validation enforces this common selection rule, while each compute-provider module owns its provider-specific semantic validation. The stack passes `compute_provider.<provider>` to the selected provider module as one nested `config` object. It also passes the provider-neutral `runner`, `github`, `ssm`, and `observability` objects without expanding them back into prefixed scalar inputs. This keeps ownership visible at the module boundary and gives future compute providers an equivalent contract to implement.
32
+
`runner-stack` selects a compute provider from the single populated typed block under `compute_provider`. For example, `compute_provider = { ec2 = { ... } }` selects EC2 and `compute_provider = { microvm = { ... } }` selects MicroVM; there is no separate `type` input that can disagree with the populated block. Exactly one provider block must be populated, and its presence must be known during planning because it determines the module graph. Native input validation enforces this common selection rule, while each compute-provider module owns its provider-specific semantic validation. The stack passes `compute_provider.<provider>` to the selected provider module as one nested `config` object. It also passes the provider-neutral `runner`, `github`, `ssm`, and `observability` objects without expanding them back into prefixed scalar inputs. This keeps ownership visible at the module boundary and gives future compute providers an equivalent contract to implement.
33
33
34
34
The common stack creates or selects the runner IAM role, but the selected provider owns the role's default trust-policy document. Each provider implements a small `trust-policy` submodule that accepts `additional_trust_policy_json` and returns the final `assume_role_policy`. The full provider separately returns its nested `provider` contract containing `policies.runner`, `policies.scale_up`, `policies.scale_down`, and `policies.pool`, component environment variables, and provider resources. The common stack uses the isolated trust-policy output when it creates the runner role and attaches the full provider's permission documents to the roles owned by the corresponding common components. A provider never creates or attaches a common IAM role.
35
35
@@ -123,7 +123,7 @@ Tags follow the same ownership model. Module tags are defaults; shared Lambda, q
123
123
124
124
Application logging settings stay together under `observability.logs`, including `level`, retention, encryption, class, and shared log-group tags.
125
125
126
-
In v1 mode, entries remain exclusively in `runners_map` and retain their flat output fields; `runners_map_v2` is empty. In v2 mode, entries are exposed exclusively through `runners_map_v2` and `runners_map` is empty. Common resources are grouped under `runner`, `scale_up`, `scale_down`, and `pool`, while provider-specific resources remain under `provider.<provider>`. The provider key is derived dynamically from the selected input block and therefore also identifies the compute provider. For example, the common runner role is available at `runners_map_v2["configuration"].runner.role`, while an EC2 selection places launch-template and runner-log artifacts under `runners_map_v2["configuration"].provider.ec2`. The `pool` value is null when no pool configuration is supplied.
126
+
In v1 mode, entries remain exclusively in `runners_map` and retain their flat output fields; `runners_map_v2` is empty. In v2 mode, entries are exposed exclusively through `runners_map_v2` and `runners_map` is empty. Common resources are grouped under `runner`, `scale_up`, `scale_down`, and `pool`, while provider-specific resources remain under `provider.<provider>`. The provider key is derived dynamically from the selected input block and therefore also identifies the compute provider. For example, the common runner role is available at `runners_map_v2["configuration"].runner.role`, an EC2 selection places launch-template and runner-log artifacts under `runners_map_v2["configuration"].provider.ec2`, and a MicroVM selection places image and execution-role references under `runners_map_v2["configuration"].provider.microvm`. The `pool` value is null when no pool configuration is supplied.
127
127
128
128
## Plan-time provider selection and ownership wrappers
|[aws_iam_policy_document.scale_down](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document)| data source |
27
+
|[aws_iam_policy_document.scale_up](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document)| data source |
28
+
29
+
## Inputs
30
+
31
+
| Name | Description | Type | Default | Required |
| <aname="input_aws_partition"></a> [aws\_partition](#input\_aws\_partition)| AWS partition used to construct IAM ARNs. |`string`|`"aws"`| no |
34
+
| <aname="input_aws_region"></a> [aws\_region](#input\_aws\_region)| AWS region used by compute-provider resources and policy documents. |`string`| n/a | yes |
35
+
| <a name="input_config"></a> [config](#input\_config) | Lambda MicroVM compute-provider configuration. Paths match `compute_provider.microvm` in the runner stack.<br/><br/>- `image_identifier`: ARN or ID of the MicroVM image used to run GitHub runners.<br/>- `image_version`: Optional MicroVM image version.<br/>- `execution_role`: Optional externally managed execution role assumed by MicroVMs. Null uses the common runner role.<br/>- `execution_role.arn`: ARN of the externally managed MicroVM execution role.<br/>- `egress_network_connectors`: Egress network connectors passed to RunMicrovm.<br/>- `idle_policy`: Optional auto-suspend and auto-resume configuration passed to RunMicrovm.<br/>- `idle_policy.max_idle_duration_seconds`: Maximum idle time before MicroVM auto-suspend.<br/>- `idle_policy.suspended_duration_seconds`: Maximum suspended time before MicroVM termination.<br/>- `idle_policy.auto_resume_enabled`: Enables automatic resume on inbound traffic while suspended.<br/>- `logging`: Optional RunMicrovm logging union. Exactly one of `cloud_watch` or `disabled` must be selected when set.<br/>- `logging.cloud_watch.log_group`: Optional CloudWatch Logs log group used by MicroVM runtime logs.<br/>- `logging.cloud_watch.log_stream`: Optional CloudWatch Logs log stream used by MicroVM runtime logs.<br/>- `logging.disabled`: Disables MicroVM runtime logging when true.<br/>- `run_hook_payload`: Optional payload delivered to the MicroVM `/run` hook. Maximum 16,384 characters.<br/>- `maximum_duration_in_seconds`: Optional maximum MicroVM lifetime. Valid range is 1 through 28,800 seconds.<br/>- `environment_variables`: Additional provider-specific Lambda environment variables merged into scale-up, scale-down, and pool.<br/>- `tags`: Tags encoded into the MicroVM runner configuration.<br/>- `iam.resource_arns`: Resource ARNs used by the generated MicroVM control-plane policies. The service is new and some actions may require `*`.<br/>- `iam.actions.scale_up`: MicroVM IAM actions used by scale-up and pool.<br/>- `iam.actions.scale_down`: MicroVM IAM actions used by scale-down.<br/>- `iam.additional_policy_json.scale_up`: Optional additional provider policy attached separately to the scale-up Lambda role.<br/>- `iam.managed_policy_arns.scale_up`: Optional managed policy attached to the scale-up Lambda role.<br/>- `iam.managed_policy_arns.pool`: Optional managed policy attached to the pool Lambda role. | <pre>object({<br/> image_identifier = string<br/> image_version = optional(string, null)<br/> execution_role = optional(object({<br/> arn = string<br/> }), null)<br/> egress_network_connectors = optional(list(string), [])<br/> idle_policy = optional(object({<br/> max_idle_duration_seconds = number<br/> suspended_duration_seconds = number<br/> auto_resume_enabled = bool<br/> }), null)<br/> logging = optional(object({<br/> cloud_watch = optional(object({<br/> log_group = optional(string, null)<br/> log_stream = optional(string, null)<br/> }), null)<br/> disabled = optional(bool, false)<br/> }), null)<br/> run_hook_payload = optional(string, null)<br/> maximum_duration_in_seconds = optional(number, null)<br/> environment_variables = optional(map(string), {})<br/> tags = optional(map(string), {})<br/> iam = optional(object({<br/> resource_arns = optional(list(string), ["*"])<br/> actions = optional(object({<br/> scale_up = optional(list(string), null)<br/> scale_down = optional(list(string), null)<br/> }), {})<br/> additional_policy_json = optional(object({<br/> scale_up = optional(string, null)<br/> }), {})<br/> managed_policy_arns = optional(object({<br/> scale_up = optional(string, null)<br/> pool = optional(string, null)<br/> }), {})<br/> }), {})<br/> })</pre> | n/a | yes |
36
+
| <aname="input_github"></a> [github](#input\_github)| GitHub Enterprise Server settings available to compute-provider bootstrap data.<br/><br/>- `enterprise_server.url`: Optional GitHub Enterprise Server base URL. Null selects GitHub.com.<br/>- `enterprise_server.ssl_verify`: Enables TLS certificate verification for GitHub Enterprise Server. | <pre>object({<br/> enterprise_server = optional(object({<br/> url = optional(string, null)<br/> ssl_verify = optional(bool, true)<br/> }), {})<br/> })</pre> |`{}`| no |
37
+
| <aname="input_observability"></a> [observability](#input\_observability)| CloudWatch Logs settings available to compute-provider runner log groups.<br/><br/>- `logs.retention_in_days`: Retention period for provider-owned runner log groups.<br/>- `logs.kms_key_id`: Optional KMS key ID or ARN used to encrypt runner log groups.<br/>- `logs.tags`: Shared log-group tags that override module-level `tags`. | <pre>object({<br/> logs = optional(object({<br/> retention_in_days = optional(number, 180)<br/> kms_key_id = optional(string, null)<br/> tags = optional(map(string), {})<br/> }), {})<br/> })</pre> |`{}`| no |
38
+
| <aname="input_prefix"></a> [prefix](#input\_prefix)| Prefix used to identify resources created for the runner stack. |`string`|`"github-actions"`| no |
39
+
| <a name="input_runner"></a> [runner](#input\_runner) | Provider-neutral runner settings consumed by compute providers.<br/><br/>- `os`: Runner operating system. Supported values are `linux`, `osx`, and `windows`.<br/>- `architecture`: Runner distribution architecture.<br/>- `boot_time_in_minutes`: Expected boot and registration duration used by scale-down and pool.<br/>- `name_prefix`: Prefix added to registered runner names.<br/>- `run_as_root`: Runs the runner service as root.<br/>- `run_as`: Operating-system user used when `run_as_root` is false.<br/>- `hooks.job_started`: Script installed as the runner job-started hook.<br/>- `hooks.job_completed`: Script installed as the runner job-completed hook.<br/>- `iam.role.arn`: Resolved runner-role ARN referenced by provider policies and resources.<br/>- `iam.role.name`: Resolved runner-role name used by provider resources.<br/>- `iam.role.managed`: Whether runner-stack manages the resolved runner role.<br/>- `iam.managed_policy_arns`: Common managed-policy ARNs returned with the provider-specific runner policies for attachment by runner-stack.<br/>- `iam.path`: IAM path available to provider-managed IAM resources. Null derives the path from `prefix`. | <pre>object({<br/> os = optional(string, "linux")<br/> architecture = optional(string, "x64")<br/> boot_time_in_minutes = optional(number, 5)<br/> name_prefix = optional(string, "")<br/> run_as_root = optional(bool, false)<br/> run_as = optional(string, "ec2-user")<br/> hooks = optional(object({<br/> job_started = optional(string, "")<br/> job_completed = optional(string, "")<br/> }), {})<br/> iam = object({<br/> role = object({<br/> arn = string<br/> name = string<br/> managed = optional(bool, true)<br/> })<br/> managed_policy_arns = optional(map(string), {})<br/> path = optional(string, null)<br/> })<br/> })</pre> | n/a | yes |
40
+
| <aname="input_ssm"></a> [ssm](#input\_ssm)| Parameter Store paths and tag scopes available to compute-provider bootstrap resources.<br/><br/>- `paths.root`: Root Parameter Store path for the runner stack.<br/>- `paths.tokens`: Path segment used for registration tokens and just-in-time configuration.<br/>- `paths.config`: Path segment used for persistent runner and provider configuration.<br/>- `tags`: Shared SSM tags that override module-level `tags`.<br/>- `parameters.tags`: Parameter-specific tags that override module-level and shared SSM tags. | <pre>object({<br/> paths = object({<br/> root = string<br/> tokens = string<br/> config = string<br/> })<br/> tags = optional(map(string), {})<br/> parameters = optional(object({<br/> tags = optional(map(string), {})<br/> }), {})<br/> })</pre> | n/a | yes |
41
+
| <aname="input_tags"></a> [tags](#input\_tags)| Base tags available to taggable compute-provider resources. Provider-specific tags override this map within their documented scopes. |`map(string)`|`{}`| no |
This internal submodule builds the MicroVM runner-role trust policy independently from runtime resources that consume the runner role. It preserves the default Lambda service trust and optionally merges an additional IAM trust policy document supplied by the common runner stack.
|[aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document)| data source |
28
+
|[aws_iam_policy_document.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document)| data source |
29
+
30
+
## Inputs
31
+
32
+
| Name | Description | Type | Default | Required |
| <aname="input_additional_trust_policy_json"></a> [additional\_trust\_policy\_json](#input\_additional\_trust\_policy\_json)| Optional IAM policy document merged with the MicroVM provider's default runner-role trust policy. |`string`|`null`| no |
35
+
36
+
## Outputs
37
+
38
+
| Name | Description |
39
+
|------|-------------|
40
+
| <aname="output_assume_role_policy"></a> [assume\_role\_policy](#output\_assume\_role\_policy)| MicroVM runner-role trust policy including any additional trust statements. |
0 commit comments