From f36c6bbb6bbcfee58502e81256c06e05982b21e0 Mon Sep 17 00:00:00 2001 From: Patrick Lee Scott Date: Wed, 11 Mar 2026 16:45:27 -0500 Subject: [PATCH 1/4] feat: use file-based env vars for e2e tests Replace hardcoded AWS account IDs, subnet IDs, and other environment-specific values with file.read("env/...") pattern. CI writes env files from GitHub repo variables (${{ vars.* }}). Workflow versions updated to v2.19.1 + feat/kcl-env-files. Implements [[tasks/e2e-env-vars-via-files]] --- .github/workflows/on-pr.yaml | 34 +++++++++++++++--- .github/workflows/on-push-main.yaml | 32 +++++++++++++++-- .gitignore | 1 + tests/e2etest-network/main.k | 53 ++++++++++++++--------------- 4 files changed, 85 insertions(+), 35 deletions(-) diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml index 0544023..e416964 100644 --- a/.github/workflows/on-pr.yaml +++ b/.github/workflows/on-pr.yaml @@ -27,7 +27,7 @@ permissions: jobs: validate: - uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.19.1 with: examples: | [ @@ -46,10 +46,10 @@ jobs: error_on_missing_schemas: true test: - uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@feat/kcl-env-files secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -60,12 +60,38 @@ jobs: aws-region: us-east-2 timeout-minutes: 30 cleanup-timeout-minutes: 30 + env-vars: | + { + "IPAM_POOL_REGIONAL_IPV4": "${{ vars.IPAM_POOL_REGIONAL_IPV4 }}", + "IPAM_POOL_REGIONAL_IPV6": "${{ vars.IPAM_POOL_REGIONAL_IPV6 }}", + "NETWORK_VPC": "${{ vars.NETWORK_VPC }}", + "NETWORK_IGW": "${{ vars.NETWORK_IGW }}", + "NETWORK_EIGW": "${{ vars.NETWORK_EIGW }}", + "NETWORK_SUBNET_PRIVATE_A": "${{ vars.NETWORK_SUBNET_PRIVATE_A }}", + "NETWORK_SUBNET_PRIVATE_B": "${{ vars.NETWORK_SUBNET_PRIVATE_B }}", + "NETWORK_SUBNET_PRIVATE_C": "${{ vars.NETWORK_SUBNET_PRIVATE_C }}", + "NETWORK_SUBNET_PUBLIC_A": "${{ vars.NETWORK_SUBNET_PUBLIC_A }}", + "NETWORK_SUBNET_PUBLIC_B": "${{ vars.NETWORK_SUBNET_PUBLIC_B }}", + "NETWORK_SUBNET_PUBLIC_C": "${{ vars.NETWORK_SUBNET_PUBLIC_C }}", + "NETWORK_RT_PUBLIC": "${{ vars.NETWORK_RT_PUBLIC }}", + "NETWORK_RT_PRIVATE_A": "${{ vars.NETWORK_RT_PRIVATE_A }}", + "NETWORK_RT_PRIVATE_B": "${{ vars.NETWORK_RT_PRIVATE_B }}", + "NETWORK_RT_PRIVATE_C": "${{ vars.NETWORK_RT_PRIVATE_C }}", + "NETWORK_RTA_PUBLIC_A": "${{ vars.NETWORK_RTA_PUBLIC_A }}", + "NETWORK_RTA_PUBLIC_B": "${{ vars.NETWORK_RTA_PUBLIC_B }}", + "NETWORK_RTA_PUBLIC_C": "${{ vars.NETWORK_RTA_PUBLIC_C }}", + "NETWORK_RTA_PRIVATE_A": "${{ vars.NETWORK_RTA_PRIVATE_A }}", + "NETWORK_RTA_PRIVATE_B": "${{ vars.NETWORK_RTA_PRIVATE_B }}", + "NETWORK_RTA_PRIVATE_C": "${{ vars.NETWORK_RTA_PRIVATE_C }}", + "NAT_GATEWAY_A": "${{ vars.NAT_GATEWAY_A }}", + "EIP_ALLOCATION_A": "${{ vars.EIP_ALLOCATION_A }}" + } publish: needs: - validate - test - uses: unbounded-tech/workflows-crossplane/.github/workflows/publish.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/publish.yaml@v2.19.1 secrets: inherit with: tag: pr-${{ github.event.pull_request.number }}-${{ github.sha }} diff --git a/.github/workflows/on-push-main.yaml b/.github/workflows/on-push-main.yaml index 140f316..a2df419 100644 --- a/.github/workflows/on-push-main.yaml +++ b/.github/workflows/on-push-main.yaml @@ -24,7 +24,7 @@ permissions: jobs: validate: - uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.19.1 with: examples: | [ @@ -43,10 +43,10 @@ jobs: error_on_missing_schemas: true test: - uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.14.2 + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@feat/kcl-env-files secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -57,6 +57,32 @@ jobs: aws-region: us-east-2 timeout-minutes: 30 cleanup-timeout-minutes: 30 + env-vars: | + { + "IPAM_POOL_REGIONAL_IPV4": "${{ vars.IPAM_POOL_REGIONAL_IPV4 }}", + "IPAM_POOL_REGIONAL_IPV6": "${{ vars.IPAM_POOL_REGIONAL_IPV6 }}", + "NETWORK_VPC": "${{ vars.NETWORK_VPC }}", + "NETWORK_IGW": "${{ vars.NETWORK_IGW }}", + "NETWORK_EIGW": "${{ vars.NETWORK_EIGW }}", + "NETWORK_SUBNET_PRIVATE_A": "${{ vars.NETWORK_SUBNET_PRIVATE_A }}", + "NETWORK_SUBNET_PRIVATE_B": "${{ vars.NETWORK_SUBNET_PRIVATE_B }}", + "NETWORK_SUBNET_PRIVATE_C": "${{ vars.NETWORK_SUBNET_PRIVATE_C }}", + "NETWORK_SUBNET_PUBLIC_A": "${{ vars.NETWORK_SUBNET_PUBLIC_A }}", + "NETWORK_SUBNET_PUBLIC_B": "${{ vars.NETWORK_SUBNET_PUBLIC_B }}", + "NETWORK_SUBNET_PUBLIC_C": "${{ vars.NETWORK_SUBNET_PUBLIC_C }}", + "NETWORK_RT_PUBLIC": "${{ vars.NETWORK_RT_PUBLIC }}", + "NETWORK_RT_PRIVATE_A": "${{ vars.NETWORK_RT_PRIVATE_A }}", + "NETWORK_RT_PRIVATE_B": "${{ vars.NETWORK_RT_PRIVATE_B }}", + "NETWORK_RT_PRIVATE_C": "${{ vars.NETWORK_RT_PRIVATE_C }}", + "NETWORK_RTA_PUBLIC_A": "${{ vars.NETWORK_RTA_PUBLIC_A }}", + "NETWORK_RTA_PUBLIC_B": "${{ vars.NETWORK_RTA_PUBLIC_B }}", + "NETWORK_RTA_PUBLIC_C": "${{ vars.NETWORK_RTA_PUBLIC_C }}", + "NETWORK_RTA_PRIVATE_A": "${{ vars.NETWORK_RTA_PRIVATE_A }}", + "NETWORK_RTA_PRIVATE_B": "${{ vars.NETWORK_RTA_PRIVATE_B }}", + "NETWORK_RTA_PRIVATE_C": "${{ vars.NETWORK_RTA_PRIVATE_C }}", + "NAT_GATEWAY_A": "${{ vars.NAT_GATEWAY_A }}", + "EIP_ALLOCATION_A": "${{ vars.EIP_ALLOCATION_A }}" + } version-and-tag: name: Version and Tag diff --git a/.gitignore b/.gitignore index 95473dc..0835f97 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ _output/ .venv/ .tmp/ tests/**/secrets +tests/**/env/ diff --git a/tests/e2etest-network/main.k b/tests/e2etest-network/main.k index 5984dcf..370b925 100644 --- a/tests/e2etest-network/main.k +++ b/tests/e2etest-network/main.k @@ -42,58 +42,55 @@ _base64_creds = base64.encode(_creds) # ============================================================================= # IPAM Pools - from aws-ipam e2e test # Get pool IDs: aws ec2 describe-ipam-pools --query 'IpamPools[*].[IpamPoolId,AddressFamily,Description]' --output table -_ipv4_private_pool_id = "ipam-pool-0607416fa3707147a" -_ipv6_private_pool_id = "ipam-pool-0ca730678e463dbfc" +_ipv4_private_pool_id = file.read("env/IPAM_POOL_REGIONAL_IPV4").strip() +_ipv6_private_pool_id = file.read("env/IPAM_POOL_REGIONAL_IPV6").strip() # Orphan policy - no Delete means resources persist in AWS after claim deletion _orphan = ["Create", "Observe", "Update", "LateInitialize"] # External names for import (leave empty for create, populate for import) -# VPC: vpc-0c20c458dcb738f21 -_vpc_external_name = "vpc-0c20c458dcb738f21" +_vpc_external_name = file.read("env/NETWORK_VPC").strip() -# Internet Gateway: igw-0a11d99e3cc584333 -_igw_external_name = "igw-0a11d99e3cc584333" +_igw_external_name = file.read("env/NETWORK_IGW").strip() -# Egress-Only Internet Gateway: eigw-02d33bcb5e87d8353 -_eigw_external_name = "eigw-02d33bcb5e87d8353" +_eigw_external_name = file.read("env/NETWORK_EIGW").strip() # Subnets _subnet_external_names = { - "public-c": "subnet-0739c3679702306eb" - "private-a": "subnet-0ba2f584c25e9435d" - "public-a": "subnet-0f17f94da9c13d3fe" - "public-b": "subnet-0f09414e8042cbee9" - "private-b": "subnet-02e4d512f8859e684" - "private-c": "subnet-0a46f41be19e3ef54" + "public-c": file.read("env/NETWORK_SUBNET_PUBLIC_C").strip() + "private-a": file.read("env/NETWORK_SUBNET_PRIVATE_A").strip() + "public-a": file.read("env/NETWORK_SUBNET_PUBLIC_A").strip() + "public-b": file.read("env/NETWORK_SUBNET_PUBLIC_B").strip() + "private-b": file.read("env/NETWORK_SUBNET_PRIVATE_B").strip() + "private-c": file.read("env/NETWORK_SUBNET_PRIVATE_C").strip() } # Route Tables _route_table_external_names = { - "public": "rtb-0ec6e6b72b4069f6d" - "private-a": "rtb-0123083a1a6980352" - "private-b": "rtb-0f3651ed2fa86b78c" - "private-c": "rtb-00bcd173ff8e26c91" + "public": file.read("env/NETWORK_RT_PUBLIC").strip() + "private-a": file.read("env/NETWORK_RT_PRIVATE_A").strip() + "private-b": file.read("env/NETWORK_RT_PRIVATE_B").strip() + "private-c": file.read("env/NETWORK_RT_PRIVATE_C").strip() } # Route Table Associations _rta_external_names = { - "public-a": "rtbassoc-0f55cb72f58eba3c6" - "public-b": "rtbassoc-0e260598fc03c1bda" - "public-c": "rtbassoc-0ed529b17080a7ff5" - "private-a": "rtbassoc-05a8500db23f7e5c4" - "private-b": "rtbassoc-04181252701b445f0" - "private-c": "rtbassoc-0f81cf5c3e798aa8c" + "public-a": file.read("env/NETWORK_RTA_PUBLIC_A").strip() + "public-b": file.read("env/NETWORK_RTA_PUBLIC_B").strip() + "public-c": file.read("env/NETWORK_RTA_PUBLIC_C").strip() + "private-a": file.read("env/NETWORK_RTA_PRIVATE_A").strip() + "private-b": file.read("env/NETWORK_RTA_PRIVATE_B").strip() + "private-c": file.read("env/NETWORK_RTA_PRIVATE_C").strip() } # NAT Gateways (populate after first run with NAT enabled) # Get NAT IDs: kubectl get natgateway -l crossplane.io/composite=hops-test -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.atProvider.id}{"\n"}{end}' # Get EIP IDs: kubectl get eip -l crossplane.io/composite=hops-test -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.atProvider.allocationId}{"\n"}{end}' _nat_external_names = { - "a": "nat-05a5e2c13be4c716a" + "a": file.read("env/NAT_GATEWAY_A").strip() } _eip_external_names = { - "a": "eipalloc-09da84030949b878c" + "a": file.read("env/EIP_ALLOCATION_A").strip() } # ============================================================================= @@ -121,7 +118,7 @@ _items = [ providerConfigRef: { name: "default" } - region: "us-east-2" + region: file.read("env/AWS_REGION").strip() tags: { "hops.ops.com.ai/test-repo": "https://github.com/hops-ops/aws-network" "hops.ops.com.ai/test-run-time": _now @@ -168,7 +165,7 @@ _items = [ providerConfigRef: { name: "default" } - region: "us-east-2" + region: file.read("env/AWS_REGION").strip() tags: { "hops.ops.com.ai/test-repo": "https://github.com/hops-ops/aws-network" "hops.ops.com.ai/test-run-time": _now From 20714f9e6b9786395062fe648518930a2702cda2 Mon Sep 17 00:00:00 2001 From: Patrick Lee Scott Date: Wed, 11 Mar 2026 17:03:59 -0500 Subject: [PATCH 2/4] chore: use e2e workflow v2.19.1 (released) Update e2e workflow ref from feat/kcl-env-files to v2.19.1. --- .github/workflows/on-pr.yaml | 2 +- .github/workflows/on-push-main.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml index e416964..3acd55b 100644 --- a/.github/workflows/on-pr.yaml +++ b/.github/workflows/on-pr.yaml @@ -49,7 +49,7 @@ jobs: uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@feat/kcl-env-files + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.19.1 secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/on-push-main.yaml b/.github/workflows/on-push-main.yaml index a2df419..40b9155 100644 --- a/.github/workflows/on-push-main.yaml +++ b/.github/workflows/on-push-main.yaml @@ -46,7 +46,7 @@ jobs: uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@feat/kcl-env-files + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.19.1 secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} From 4888a890761049cb89cdaa26e430e86f9793a3bd Mon Sep 17 00:00:00 2001 From: Patrick Lee Scott Date: Wed, 11 Mar 2026 17:23:44 -0500 Subject: [PATCH 3/4] chore: add write-env-files: true for explicit env file opt-in --- .github/workflows/on-pr.yaml | 1 + .github/workflows/on-push-main.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml index 3acd55b..4fd3987 100644 --- a/.github/workflows/on-pr.yaml +++ b/.github/workflows/on-pr.yaml @@ -60,6 +60,7 @@ jobs: aws-region: us-east-2 timeout-minutes: 30 cleanup-timeout-minutes: 30 + write-env-files: true env-vars: | { "IPAM_POOL_REGIONAL_IPV4": "${{ vars.IPAM_POOL_REGIONAL_IPV4 }}", diff --git a/.github/workflows/on-push-main.yaml b/.github/workflows/on-push-main.yaml index 40b9155..c33d68f 100644 --- a/.github/workflows/on-push-main.yaml +++ b/.github/workflows/on-push-main.yaml @@ -57,6 +57,7 @@ jobs: aws-region: us-east-2 timeout-minutes: 30 cleanup-timeout-minutes: 30 + write-env-files: true env-vars: | { "IPAM_POOL_REGIONAL_IPV4": "${{ vars.IPAM_POOL_REGIONAL_IPV4 }}", From 253e1532cc34c12cb5eb79d888327042399c76db Mon Sep 17 00:00:00 2001 From: Patrick Lee Scott Date: Wed, 11 Mar 2026 18:28:35 -0500 Subject: [PATCH 4/4] chore: update workflows-crossplane to v2.20.0 (write-env-files support) --- .github/workflows/on-pr.yaml | 8 ++++---- .github/workflows/on-push-main.yaml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml index 4fd3987..b5a5d17 100644 --- a/.github/workflows/on-pr.yaml +++ b/.github/workflows/on-pr.yaml @@ -27,7 +27,7 @@ permissions: jobs: validate: - uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.20.0 with: examples: | [ @@ -46,10 +46,10 @@ jobs: error_on_missing_schemas: true test: - uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.20.0 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.20.0 secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -92,7 +92,7 @@ jobs: needs: - validate - test - uses: unbounded-tech/workflows-crossplane/.github/workflows/publish.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/publish.yaml@v2.20.0 secrets: inherit with: tag: pr-${{ github.event.pull_request.number }}-${{ github.sha }} diff --git a/.github/workflows/on-push-main.yaml b/.github/workflows/on-push-main.yaml index c33d68f..2d3cb2f 100644 --- a/.github/workflows/on-push-main.yaml +++ b/.github/workflows/on-push-main.yaml @@ -24,7 +24,7 @@ permissions: jobs: validate: - uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/validate.yaml@v2.20.0 with: examples: | [ @@ -43,10 +43,10 @@ jobs: error_on_missing_schemas: true test: - uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/test.yaml@v2.20.0 e2e: - uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.19.1 + uses: unbounded-tech/workflows-crossplane/.github/workflows/e2e.yaml@v2.20.0 secrets: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}