Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5743d33
refactor(runner-config): align GitHub configuration contract
edersonbrilhante Sep 10, 2026
a4a5ff1
Revert "refactor(runner-config): align GitHub configuration contract"
edersonbrilhante Sep 10, 2026
e4caa1a
fix(runner-config): allow missing installation IDs
edersonbrilhante Sep 9, 2026
ebe1cf4
docs: auto update terraform docs
github-actions[bot] Sep 9, 2026
c94f17b
fix(webhook): require installation ID parameter lists
edersonbrilhante Sep 10, 2026
16ae682
docs: auto update terraform docs
github-actions[bot] Sep 10, 2026
51470fe
test(runner-config): cover additional app installation IDs
edersonbrilhante Sep 10, 2026
adc30c4
docs: auto update terraform docs
github-actions[bot] Sep 10, 2026
c3b2e2b
test(runner-config): keep additional app fixture focused
edersonbrilhante Sep 10, 2026
523ddf4
docs: auto update terraform docs
github-actions[bot] Sep 10, 2026
a19185b
fix(multi-runner): make v2 inputs independent
edersonbrilhante Sep 4, 2026
3505137
fix(multi-runner): validate v1 and v2 inputs
edersonbrilhante Sep 4, 2026
d48eeac
test(multi-runner): remove v2 feature acknowledgement
edersonbrilhante Sep 8, 2026
450b5a4
test(multi-runner): acknowledge experimental v2 feature
edersonbrilhante Sep 9, 2026
87444df
test(multi-runner): scope v2 feature acknowledgement to v2 tests
edersonbrilhante Sep 9, 2026
dfc944e
test(ministack): cover multi-runner-v2 example
edersonbrilhante Sep 8, 2026
12517a2
feat(compute-providers): add Lambda MicroVM Terraform provider
edersonbrilhante Sep 3, 2026
2029567
fix(ci): correct MicroVM module matrix paths
edersonbrilhante Sep 11, 2026
87b8d0f
fix(ministack): restore test README
edersonbrilhante Sep 16, 2026
d78d6f4
feat(multi-runner): integrate Lambda MicroVM provider
edersonbrilhante Sep 3, 2026
477afa9
docs: auto update terraform docs
github-actions[bot] Sep 3, 2026
d751a2a
test(multi-runner): cover MicroVM provider routing
edersonbrilhante Sep 4, 2026
63a0286
fix(multi-runner): validate MicroVM v2 lanes
edersonbrilhante Sep 4, 2026
7a2ee1f
fix(multi-runner): default translated MicroVM config
edersonbrilhante Sep 4, 2026
f2df32e
fix(multi-runner): separate provider validation
edersonbrilhante Sep 4, 2026
4683c79
fix(multi-runner): require one compute provider
edersonbrilhante Sep 4, 2026
3d1c6ec
docs: auto update terraform docs
github-actions[bot] Sep 16, 2026
a46b9b9
fix(multi-runner): move MicroVM schema to multi-runner config
edersonbrilhante Sep 16, 2026
56d529d
fix(multi-runner): remove invalid matcherless test
edersonbrilhante Sep 16, 2026
f1afd78
docs: auto update terraform docs
github-actions[bot] Sep 17, 2026
a8d86a6
Merge branch 'microvm-provider-independent' into microvm-integration-…
edersonbrilhante Sep 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions modules/multi-runner/README.md

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions modules/multi-runner/config.experimental.resolved.tf
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,54 @@ locals {
}
tags = merge(local.normalized_config.compute_provider.aws.ec2.tags, v.compute_provider.aws.ec2.tags)
})
microvm = v.compute_provider.aws.microvm == null ? null : merge(v.compute_provider.aws.microvm, {
image_arn = try(coalesce(v.compute_provider.aws.microvm.image_arn, local.normalized_config.compute_provider.aws.microvm.image_arn), null)
image_version = try(coalesce(v.compute_provider.aws.microvm.image_version, local.normalized_config.compute_provider.aws.microvm.image_version), null)
ingress_network_connectors = v.compute_provider.aws.microvm.ingress_network_connectors != null ? (
v.compute_provider.aws.microvm.ingress_network_connectors
) : local.normalized_config.compute_provider.aws.microvm.ingress_network_connectors
egress_network_connectors = v.compute_provider.aws.microvm.egress_network_connectors != null ? (
v.compute_provider.aws.microvm.egress_network_connectors
) : local.normalized_config.compute_provider.aws.microvm.egress_network_connectors
cloudwatch_agent = {
enabled = coalesce(
v.compute_provider.aws.microvm.cloudwatch_agent.enabled,
local.normalized_config.compute_provider.aws.microvm.cloudwatch_agent.enabled,
)
config = try(coalesce(
v.compute_provider.aws.microvm.cloudwatch_agent.config,
local.normalized_config.compute_provider.aws.microvm.cloudwatch_agent.config,
), null)
}
log_files = v.compute_provider.aws.microvm.log_files != null ? (
v.compute_provider.aws.microvm.log_files
) : local.normalized_config.compute_provider.aws.microvm.log_files
environment_variables = merge(
local.normalized_config.compute_provider.aws.microvm.environment_variables,
v.compute_provider.aws.microvm.environment_variables,
)
iam = {
resource_arns = {
images = v.compute_provider.aws.microvm.iam.resource_arns.images != null ? (
v.compute_provider.aws.microvm.iam.resource_arns.images
) : local.normalized_config.compute_provider.aws.microvm.iam.resource_arns.images
}
additional_policy_json = {
scale_up = try(coalesce(
v.compute_provider.aws.microvm.iam.additional_policy_json.scale_up,
local.normalized_config.compute_provider.aws.microvm.iam.additional_policy_json.scale_up,
), null)
}
managed_policies = {
scale_up = v.compute_provider.aws.microvm.iam.managed_policies.scale_up != null ? (
v.compute_provider.aws.microvm.iam.managed_policies.scale_up
) : local.normalized_config.compute_provider.aws.microvm.iam.managed_policies.scale_up
pool = v.compute_provider.aws.microvm.iam.managed_policies.pool != null ? (
v.compute_provider.aws.microvm.iam.managed_policies.pool
) : local.normalized_config.compute_provider.aws.microvm.iam.managed_policies.pool
}
}
})
}
}
})
Expand Down
48 changes: 48 additions & 0 deletions modules/multi-runner/config.experimental.translation.tf
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,30 @@ locals {
}
}
}
microvm = {
image_arn = null
image_version = null
ingress_network_connectors = []
egress_network_connectors = []
cloudwatch_agent = {
enabled = true
config = null
}
log_files = null
environment_variables = {}
iam = {
resource_arns = {
images = null
}
additional_policy_json = {
scale_up = null
}
managed_policies = {
scale_up = null
pool = null
}
}
}
}
}

Expand Down Expand Up @@ -554,6 +578,30 @@ locals {
log_files = v.runner_config.runner_log_files
tags = v.runner_config.runner_ec2_tags
}
microvm = {
image_arn = null
image_version = null
ingress_network_connectors = []
egress_network_connectors = []
cloudwatch_agent = {
enabled = true
config = null
}
log_files = null
environment_variables = {}
iam = {
resource_arns = {
images = null
}
additional_policy_json = {
scale_up = null
}
managed_policies = {
scale_up = null
pool = null
}
}
}
}
}
}
Expand Down
126 changes: 126 additions & 0 deletions modules/multi-runner/tests/config-resolution.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ run "v1_stable_inputs_translate_into_effective_base" {
&& local.resolved_config.multi_runner_config["stable"].runner.group_name == "v1-lane"
&& local.resolved_config.multi_runner_config["stable"].orchestration_provider.webhook.runner.maximum_count == 2
&& toset(local.resolved_config.multi_runner_config["stable"].compute_provider.aws.ec2.instance_types) == toset(["m5.large"])
&& local.resolved_config.multi_runner_config["stable"].compute_provider.aws.microvm.image_arn == null
&& local.resolved_config.multi_runner_config["stable"].compute_provider.aws.microvm.cloudwatch_agent.enabled
&& length(local.resolved_config.multi_runner_config["stable"].compute_provider.aws.microvm.environment_variables) == 0
&& toset(local.effective_config.multi_runner_config["stable"].runner.labels) == toset(["linux", "self-hosted", "x64"])
)
error_message = "Stable v1 inputs must translate into the effective experimental base without leaking v2 globals."
Expand Down Expand Up @@ -513,3 +516,126 @@ run "v2_inputs_reject_legacy_runner_config" {
}
}
}

run "v2_microvm_inputs_route_to_microvm_provider" {
command = plan

variables {
global_config = {
runner = {
os = "linux"
architecture = "arm64"
}
}

global_config_github = {
app = {
key_base64 = "experimental-app-key"
id = "experimental-app-id"
webhook_secret = "experimental-webhook-secret"
}
}

global_config_lambda = {
artifact = {
s3 = {
bucket = "global-lambda-artifacts"
}
}
}

global_config_orchestration_provider = {
webhook = {
eventbridge = {
enabled = false
}
runner = {
ephemeral = true
jit_config_enabled = true
}
lambda = {
artifact = {
s3 = {
key = "global-runners.zip"
}
}
webhook = {
artifact = {
s3 = {
key = "global-webhook.zip"
}
}
}
}
}
}

global_config_ssm = {
housekeeper = {
lambda = {
artifact = {
s3 = {
key = "global-housekeeper.zip"
}
}
}
}
}

global_config_compute_provider = {
aws = {
microvm = {
image_arn = "arn:aws:lambda:eu-west-1:123456789012:microvm-image:global"
image_version = "7"
}
}
}

multi_runner_config = {
microvm = {
runner = {
name_prefix = "microvm-"
}
orchestration_provider = {
webhook = {
matcherConfig = {
labelMatchers = [["microvm"]]
}
}
}
compute_provider = {
aws = {
microvm = {
image_version = "8"
}
}
}
}
}
}

assert {
condition = (
local.use_v2_config
&& keys(local.resolved_config.multi_runner_config) == ["microvm"]
&& local.resolved_config.multi_runner_config["microvm"].runner.os == "linux"
&& local.resolved_config.multi_runner_config["microvm"].runner.architecture == "arm64"
&& local.resolved_config.multi_runner_config["microvm"].compute_provider.aws.ec2 == null
&& local.resolved_config.multi_runner_config["microvm"].compute_provider.aws.microvm.image_arn == "arn:aws:lambda:eu-west-1:123456789012:microvm-image:global"
&& local.resolved_config.multi_runner_config["microvm"].compute_provider.aws.microvm.image_version == "8"
&& local.effective_config.orchestration_provider.webhook.lambda.webhook.artifact.s3.key == "global-webhook.zip"
)
error_message = "Experimental MicroVM lanes must resolve Linux ARM64 settings, inherit global provider values, and place the webhook artifact key under lambda.webhook.artifact."
}

assert {
condition = (
length(module.runners) == 0
&& keys(module.runner_configs) == ["microvm"]
&& output.runners_map_v2["microvm"].provider.aws.ec2 == null
&& output.runners_map_v2["microvm"].provider.aws.microvm.image_arn == "arn:aws:lambda:eu-west-1:123456789012:microvm-image:global"
&& output.runners_map_v2["microvm"].provider.aws.microvm.image_version == "8"
)
error_message = "Experimental MicroVM lanes must route through module.runner_configs and expose the MicroVM provider contract without an EC2 provider."
}
}
48 changes: 0 additions & 48 deletions modules/multi-runner/tests/config-translation.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -522,54 +522,6 @@ run "non_empty_v2_map_is_authoritative" {

}

run "v2_entry_without_matcher_config_is_authoritative" {
command = plan

variables {
experimental_features = ["multi-runner-v2"]

global_config_compute_provider = {
aws = {
ec2 = {
runner_binaries = {
enabled = false
}
}
}
}

multi_runner_config = {
no_matcher = {
runner = {
os = "linux"
architecture = "x64"
}
orchestration_provider = {
webhook = {}
}
compute_provider = {
aws = {
ec2 = {
vpc_id = "vpc-no-matcher"
subnet_ids = ["subnet-no-matcher"]
instance_types = ["m5.large"]
}
}
}
}
}
}

assert {
condition = (
local.use_v2_config
&& toset(keys(local.normalized_config.multi_runner_config)) == toset(["no_matcher"])
&& try(local.normalized_config.multi_runner_config["no_matcher"].orchestration_provider.webhook.matcherConfig, null) == null
)
error_message = "A v2 runner entry must be recognized without requiring matcher configuration."
}
}

run "lane_values_override_experimental_globals" {
command = plan

Expand Down
42 changes: 37 additions & 5 deletions modules/multi-runner/validations.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,45 @@ resource "terraform_data" "validate_v2" {
condition = alltrue([
for config in local.resolved_config.multi_runner_config : (
try(config.orchestration_provider.webhook != null, false) &&
try(config.compute_provider.aws.ec2 != null, false) &&
try(length(config.compute_provider.aws.ec2.instance_types) > 0, false) &&
try(config.compute_provider.aws.ec2.vpc_id != null, false) &&
try(length(config.compute_provider.aws.ec2.subnet_ids) > 0, false)
try(length(config.orchestration_provider.webhook.matcherConfig.labelMatchers) > 0, false)
)
])
error_message = "Each experimental v2 runner lane requires a webhook provider, EC2 instance_types, vpc_id, and at least one subnet."
error_message = "Each experimental v2 runner lane requires a webhook matcher."
}

precondition {
condition = alltrue([
for config in local.resolved_config.multi_runner_config : length([
for provider_config in [
try(config.compute_provider.aws.ec2, null),
try(config.compute_provider.aws.microvm, null),
] : provider_config if provider_config != null
]) == 1
])
error_message = "Each experimental v2 runner lane requires exactly one compute provider. Supported providers: aws.ec2, aws.microvm."
}

precondition {
condition = alltrue([
for config in local.resolved_config.multi_runner_config : (
!try(config.compute_provider.aws.ec2 != null, false) || (
try(length(config.compute_provider.aws.ec2.instance_types) > 0, false) &&
try(config.compute_provider.aws.ec2.vpc_id != null, false) &&
try(length(config.compute_provider.aws.ec2.subnet_ids) > 0, false)
)
)
])
error_message = "Each experimental v2 EC2 runner lane requires instance_types, vpc_id, and at least one subnet."
}

precondition {
condition = alltrue([
for config in local.resolved_config.multi_runner_config : (
!try(config.compute_provider.aws.microvm != null, false) ||
try(config.compute_provider.aws.microvm.image_arn != null, false)
)
])
error_message = "Each experimental v2 MicroVM runner lane requires image_arn."
}
}
}
Loading
Loading