From ecc8d0ccc220b9ed35a6afa8af60e7ac8c323bf8 Mon Sep 17 00:00:00 2001 From: Tomas Gerulaitis Date: Fri, 24 Jul 2026 11:07:10 +0100 Subject: [PATCH 1/3] Replace prebuilt Google provider with auto gen This allows us to use the latest Google provider beyond the 6.50.0 that's available as a prebuilt package. --- .github/workflows/check.yml | 6 ++++ .github/workflows/npm-publish-beta.yml | 41 +++++++++++++++----------- .github/workflows/npm-publish.yml | 41 +++++++++++++++----------- README.md | 12 ++++++-- cdktf.json | 7 +++-- package-lock.json | 18 ++--------- package.json | 12 +++++++- providers/google.ts | 1 + stacks/gcp/GcpStack.ts | 40 ++++++++++++++----------- 9 files changed, 103 insertions(+), 75 deletions(-) create mode 100644 providers/google.ts diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 848a77c..8f3b1ed 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -11,6 +11,12 @@ jobs: - uses: actions/setup-node@v2 with: node-version: '20.x' + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: '1.14.8' + - name: Install run: npm ci - name: Build diff --git a/.github/workflows/npm-publish-beta.yml b/.github/workflows/npm-publish-beta.yml index ea7a124..230f785 100644 --- a/.github/workflows/npm-publish-beta.yml +++ b/.github/workflows/npm-publish-beta.yml @@ -13,19 +13,24 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - + - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' - + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: '1.14.8' + - name: Install dependencies run: npm ci - + - name: Build run: npm run build - + - name: Run tests run: npm run test @@ -34,10 +39,10 @@ jobs: run: | # Get the current version from package.json CURRENT_VERSION=$(node -p "require('./package.json').version") - + # Generate a timestamp for uniqueness TIMESTAMP=$(date +"%Y%m%d%H%M%S") - + # For PR: use PR number in version if [[ "${{ github.event_name }}" == "pull_request" ]]; then BETA_VERSION="$CURRENT_VERSION-beta.pr.${{ github.event.pull_request.number }}.$TIMESTAMP" @@ -46,13 +51,13 @@ jobs: SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7) BETA_VERSION="$CURRENT_VERSION-beta.$SHORT_SHA.$TIMESTAMP" fi - + # Set output for use in next step echo "version=$BETA_VERSION" >> $GITHUB_OUTPUT - + # Update package.json with new version npm version $BETA_VERSION --no-git-tag-version - + - name: Publish beta to npm run: npm publish --tag beta --access public env: @@ -72,12 +77,12 @@ jobs: } in_section == 1 { print; } ' CHANGELOG.md) - + # Store changelog content in output variable, handling multiline output echo "changelog<> $GITHUB_OUTPUT echo "$CHANGELOG_CONTENT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - + - name: Create GitHub Pre-release uses: actions/github-script@v6 with: @@ -86,7 +91,7 @@ jobs: const version = process.env.BETA_VERSION; const changelog = process.env.CHANGELOG; const eventType = process.env.GITHUB_EVENT_NAME; - + let releaseTitle, releaseTag; if (eventType === 'pull_request') { const prNumber = process.env.PR_NUMBER; @@ -97,7 +102,7 @@ jobs: releaseTitle = `Beta Release (${shortSha}): ${version}`; releaseTag = `beta-${shortSha}`; } - + // Delete existing tag if it exists try { await github.rest.git.deleteRef({ @@ -109,7 +114,7 @@ jobs: } catch (error) { console.log(`Tag ${releaseTag} doesn't exist or couldn't be deleted: ${error.message}`); } - + // Try to delete existing release if it exists try { const { data: releases } = await github.rest.repos.listReleases({ @@ -117,7 +122,7 @@ jobs: repo: context.repo.repo, per_page: 100 }); - + const existingRelease = releases.find(release => release.tag_name === releaseTag); if (existingRelease) { console.log(`Deleting existing release with ID: ${existingRelease.id}`); @@ -130,7 +135,7 @@ jobs: } catch (error) { console.log(`Error checking/deleting existing release: ${error.message}`); } - + // Create a new release try { const { data } = await github.rest.repos.createRelease({ @@ -145,7 +150,7 @@ jobs: draft: false, prerelease: true }); - + console.log(`Created pre-release: ${data.html_url}`); } catch (error) { console.log(`Error creating release: ${error.message}`); @@ -168,7 +173,7 @@ jobs: const version = process.env.BETA_VERSION; const packageName = '@space48/cloud-seed'; const installCmd = `npm install ${packageName}@${version}`; - + github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 1c378af..f0caf4c 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -10,22 +10,27 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - + - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' - + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: '1.14.8' + - name: Install dependencies run: npm ci - + - name: Build run: npm run build - + - name: Run tests run: npm run test - + - name: Get package version id: package-version run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT @@ -34,16 +39,16 @@ jobs: run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - + - name: Extract changelog for version id: extract-changelog run: | VERSION="v${{ steps.package-version.outputs.version }}" echo "Extracting changelog for $VERSION" - + # Create a tag for the version git tag $VERSION - + # Extract changelog for the current version CHANGELOG_CONTENT=$(awk -v ver="$VERSION" ' BEGIN { in_section = 0; } @@ -53,12 +58,12 @@ jobs: } in_section == 1 { print; } ' CHANGELOG.md) - + # Store changelog content in output variable, handling multiline output echo "changelog<> $GITHUB_OUTPUT echo "$CHANGELOG_CONTENT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - + - name: Create GitHub Release uses: actions/github-script@v6 with: @@ -66,7 +71,7 @@ jobs: script: | const version = process.env.PACKAGE_VERSION; const changelog = process.env.CHANGELOG; - + const { data } = await github.rest.repos.createRelease({ owner: context.repo.owner, repo: context.repo.repo, @@ -76,12 +81,12 @@ jobs: draft: false, prerelease: false }); - + console.log(`Created release: ${data.html_url}`); env: PACKAGE_VERSION: ${{ steps.package-version.outputs.version }} CHANGELOG: ${{ steps.extract-changelog.outputs.changelog }} - + - name: Find related PRs and comment uses: actions/github-script@v6 with: @@ -90,20 +95,20 @@ jobs: const version = process.env.PACKAGE_VERSION; const packageName = '@space48/cloud-seed'; const installCmd = `npm install ${packageName}@${version}`; - + // Get the commit message to find PR number const { data: commit } = await github.rest.repos.getCommit({ owner: context.repo.owner, repo: context.repo.repo, ref: context.sha }); - + // Look for PR references in the commit message (like "Merge pull request #123") const prMatch = commit.commit.message.match(/Merge pull request #(\d+)/i); - + if (prMatch && prMatch[1]) { const prNumber = parseInt(prMatch[1], 10); - + // Comment on the PR await github.rest.issues.createComment({ issue_number: prNumber, @@ -111,7 +116,7 @@ jobs: repo: context.repo.repo, body: `🚀 New version published: **${version}**\n\nThis version has been published to npm and is now available.\n\nYou can install it with:\n\`\`\`bash\n${installCmd}\n\`\`\`` }); - + console.log(`Commented on PR #${prNumber} about the new release ${version}`); } else { console.log('No PR reference found in the commit message. Skipping comment.'); diff --git a/README.md b/README.md index ab3a98a..a943db5 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ export const runtimeConfig: GcpConfig = { If your function needs access to resources on a VPC network (e.g. a back-office service over an IPSec VPN), you can configure it to route egress traffic through a VPC. All VPC settings are grouped under the `vpc` key in `runtimeConfig`. -> **Note:** VPC resources (connectors, networks, subnets) must already exist in your GCP project. Cloud Seed will configure the function to use them but will not create them. For gen1 functions, only the `connector` option is supported — `network` and `subnet` are ignored. For gen2 functions, if `network` or `subnet` is provided, direct VPC egress is used and the `connector` setting is ignored. Direct VPC egress requires `@cdktf/provider-google` to be built against Terraform Google provider >= 7.x. +> **Note:** VPC resources (connectors, networks, subnets) must already exist in your GCP project. Cloud Seed will configure the function to use them but will not create them. For gen1 functions, only the `connector` option is supported — `network` and `subnet` are ignored. For gen2 functions, if `network` or `subnet` is provided, direct VPC egress is used and the `connector` setting is ignored. Direct VPC egress uses the generated Google provider bindings included with this package. > **Note:** These options are incompatible with static IP settings. If a function is configured to use a static IP address, it won't be able to access VPN resources. @@ -384,7 +384,7 @@ This package can also be called via a JS API. ```typescript import { build, BaseConfig } from "@space48/cloud-seed"; -import GoogleProvider from "@cdktf/provider-google"; +import { provider as GoogleProvider, storageBucket } from "@space48/cloud-seed/providers/google"; import { GcsBackend, TerraformStack } from "cdktf"; import { Construct } from "constructs"; @@ -403,7 +403,7 @@ class CustomStack extends TerraformStack { /** * Example infrastructure */ - new GoogleProvider.StorageBucket(this, "CustomBucket", { + new storageBucket.StorageBucket(this, "CustomBucket", { name: `my-custom-bucket-${process.env.ENVIRONMENT}`, location: options.cloud.gcp.region.toUpperCase(), storageClass: "STANDARD", @@ -419,6 +419,12 @@ new CustomStack(app, "CustomStack", config); app.synth(); ``` + +The generated Google provider bindings are exported from +`@space48/cloud-seed/providers/google`. Consumer applications can use these bindings for +additional infrastructure without running `cdktf provider add`. Cloud Seed currently generates +them from Terraform Google provider `7.41.0`; the Terraform provider is downloaded during the +normal `terraform init` step. # Cloud functions gen 2 It is recommended by google to use the [gen 2](https://cloud.google.com/functions/docs/concepts/version-comparison) functions wherever possible. diff --git a/cdktf.json b/cdktf.json index bb9c6d2..c67eccf 100644 --- a/cdktf.json +++ b/cdktf.json @@ -1,9 +1,12 @@ { "language": "typescript", "app": "node dist/bin/entrypoint.js build --env $ENVIRONMENT", - "terraformProviders": [], + "terraformProviders": [ + "hashicorp/google@7.41.0" + ], "context": { "excludeStackIdFromLogicalIds": "true", "allowSepCharsInLogicalIds": "true" - } + }, + "projectId": "aa51f85a-d36c-4b9c-bc2f-8ebf3d963542" } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5827692..154ce94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "@space48/cloud-seed", - "version": "5.0.2", + "version": "5.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@space48/cloud-seed", - "version": "5.0.2", + "version": "5.1.0", "license": "MIT", "dependencies": { "@cdktf/provider-archive": "^10.3.0", - "@cdktf/provider-google": "^14.11.0", "arg": "^5.0.2", "cdktf": "^0.20.10", "cdktf-cli": "^0.20.10", @@ -1031,19 +1030,6 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "license": "MIT" }, - "node_modules/@cdktf/provider-google": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/@cdktf/provider-google/-/provider-google-14.11.0.tgz", - "integrity": "sha512-LqDyy+6+cRlf2VEU1XwvuCCqpW4qyaxlhkMDlt212oHpyThNC4S0M8BVhhpRdcpN5PZ1C4LO+0MbkZ3M6+5aCA==", - "license": "MPL-2.0", - "engines": { - "node": ">= 18.12.0" - }, - "peerDependencies": { - "cdktf": "^0.20.0", - "constructs": "^10.3.0" - } - }, "node_modules/@cdktf/provider-schema": { "version": "0.20.10", "resolved": "https://registry.npmjs.org/@cdktf/provider-schema/-/provider-schema-0.20.10.tgz", diff --git a/package.json b/package.json index 88bb3a4..3640c29 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,17 @@ "version": "5.1.0", "description": "Cloud infrastructure automation tool that uses Terraform CDK.", "main": "dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./providers/google": { + "types": "./dist/providers/google.d.ts", + "default": "./dist/providers/google.js" + }, + "./schemas/*": "./schemas/*" + }, "bin": { "cloud-seed": "dist/bin/entrypoint.js" }, @@ -30,7 +41,6 @@ "license": "MIT", "dependencies": { "@cdktf/provider-archive": "^10.3.0", - "@cdktf/provider-google": "^14.11.0", "arg": "^5.0.2", "cdktf": "^0.20.10", "cdktf-cli": "^0.20.10", diff --git a/providers/google.ts b/providers/google.ts new file mode 100644 index 0000000..ff52326 --- /dev/null +++ b/providers/google.ts @@ -0,0 +1 @@ +export * from "../.gen/providers/google"; diff --git a/stacks/gcp/GcpStack.ts b/stacks/gcp/GcpStack.ts index 85ee289..a936b0b 100644 --- a/stacks/gcp/GcpStack.ts +++ b/stacks/gcp/GcpStack.ts @@ -21,7 +21,7 @@ import { storageBucketObject, vpcAccessConnector, cloudRunServiceIamMember, -} from "@cdktf/provider-google"; +} from "../../providers/google"; import { provider as archiveProvider, dataArchiveFile } from "@cdktf/provider-archive"; import { StackOptions, GcpFunction } from "./types"; @@ -168,6 +168,28 @@ export default class GcpStack extends TerraformStack { maxInstanceCount: func.maxInstances, minInstanceCount: func.minInstances, environmentVariables, + ...(func.vpc?.network || func.vpc?.subnet + ? { + directVpcNetworkInterface: [ + { + ...(func.vpc.network !== undefined ? { network: func.vpc.network } : {}), + ...(func.vpc.subnet !== undefined ? { subnetwork: func.vpc.subnet } : {}), + }, + ], + directVpcEgress: + func.vpc.egressSettings === "all_traffic" + ? "VPC_EGRESS_ALL_TRAFFIC" + : "VPC_EGRESS_PRIVATE_RANGES_ONLY", + } + : func.vpc?.connector + ? { + vpcConnector: func.vpc.connector, + vpcConnectorEgressSettings: + func.vpc.egressSettings === "all_traffic" + ? "ALL_TRAFFIC" + : "PRIVATE_RANGES_ONLY", + } + : {}), }, location: this.options.gcpOptions.region, ...this.generateFunction2TriggerConfig(func, scheduledTopic), @@ -178,22 +200,6 @@ export default class GcpStack extends TerraformStack { if (func.type === "scheduledJob") { this.configureScheduledHttpFunction2(func, cloudFunc); } - if (func.vpc?.network || func.vpc?.subnet) { - cloudFunc.addOverride("service_config.direct_vpc_network_interface", { - ...(func.vpc?.network !== undefined ? { network: func.vpc.network } : {}), - ...(func.vpc?.subnet !== undefined ? { subnetwork: func.vpc.subnet } : {}), - }); - cloudFunc.addOverride( - "service_config.direct_vpc_egress", - func.vpc.egressSettings === "all_traffic" - ? "VPC_EGRESS_ALL_TRAFFIC" - : "VPC_EGRESS_PRIVATE_RANGES_ONLY", - ); - } else if (func.vpc?.connector) { - cloudFunc.serviceConfig.vpcConnector = func.vpc.connector; - cloudFunc.serviceConfig.vpcConnectorEgressSettings = - func.vpc.egressSettings === "all_traffic" ? "ALL_TRAFFIC" : "PRIVATE_RANGES_ONLY"; - } } // Create pubsub topics if they don't exist already. From d13c339a78e2e82d7c7614f8a331b7ca3d3b6df4 Mon Sep 17 00:00:00 2001 From: Tomas Gerulaitis Date: Fri, 24 Jul 2026 11:57:52 +0100 Subject: [PATCH 2/3] Replace prebuilt archive provider with auto gen --- README.md | 4 ++++ cdktf.json | 3 ++- package-lock.json | 14 -------------- package.json | 5 ++++- providers/archive.ts | 1 + stacks/gcp/GcpStack.ts | 2 +- 6 files changed, 12 insertions(+), 17 deletions(-) create mode 100644 providers/archive.ts diff --git a/README.md b/README.md index a943db5..bcabdc8 100644 --- a/README.md +++ b/README.md @@ -425,6 +425,10 @@ The generated Google provider bindings are exported from additional infrastructure without running `cdktf provider add`. Cloud Seed currently generates them from Terraform Google provider `7.41.0`; the Terraform provider is downloaded during the normal `terraform init` step. + +The generated Archive provider bindings are similarly exported from +`@space48/cloud-seed/providers/archive`. They are generated from Terraform Archive provider +`2.8.0`. # Cloud functions gen 2 It is recommended by google to use the [gen 2](https://cloud.google.com/functions/docs/concepts/version-comparison) functions wherever possible. diff --git a/cdktf.json b/cdktf.json index c67eccf..4944764 100644 --- a/cdktf.json +++ b/cdktf.json @@ -2,7 +2,8 @@ "language": "typescript", "app": "node dist/bin/entrypoint.js build --env $ENVIRONMENT", "terraformProviders": [ - "hashicorp/google@7.41.0" + "hashicorp/google@7.41.0", + "hashicorp/archive@2.8.0" ], "context": { "excludeStackIdFromLogicalIds": "true", diff --git a/package-lock.json b/package-lock.json index 154ce94..d8c0921 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "5.1.0", "license": "MIT", "dependencies": { - "@cdktf/provider-archive": "^10.3.0", "arg": "^5.0.2", "cdktf": "^0.20.10", "cdktf-cli": "^0.20.10", @@ -916,19 +915,6 @@ "prebuild-install": "^7.1.1" } }, - "node_modules/@cdktf/provider-archive": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@cdktf/provider-archive/-/provider-archive-10.3.0.tgz", - "integrity": "sha512-y5kAiCs+Ow0tOywsSx4OSME2a6VzCsvbkGMCXfyOCwJdoZN01yAIyLyVjtx/R25Vj20Q7EMC6zkE81dXSAh4Tw==", - "license": "MPL-2.0", - "engines": { - "node": ">= 18.12.0" - }, - "peerDependencies": { - "cdktf": "^0.20.0", - "constructs": "^10.3.0" - } - }, "node_modules/@cdktf/provider-generator": { "version": "0.20.10", "resolved": "https://registry.npmjs.org/@cdktf/provider-generator/-/provider-generator-0.20.10.tgz", diff --git a/package.json b/package.json index 3640c29..750cede 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,10 @@ "types": "./dist/providers/google.d.ts", "default": "./dist/providers/google.js" }, + "./providers/archive": { + "types": "./dist/providers/archive.d.ts", + "default": "./dist/providers/archive.js" + }, "./schemas/*": "./schemas/*" }, "bin": { @@ -40,7 +44,6 @@ "author": "Space48 ", "license": "MIT", "dependencies": { - "@cdktf/provider-archive": "^10.3.0", "arg": "^5.0.2", "cdktf": "^0.20.10", "cdktf-cli": "^0.20.10", diff --git a/providers/archive.ts b/providers/archive.ts new file mode 100644 index 0000000..49af285 --- /dev/null +++ b/providers/archive.ts @@ -0,0 +1 @@ +export * from "../.gen/providers/archive"; diff --git a/stacks/gcp/GcpStack.ts b/stacks/gcp/GcpStack.ts index a936b0b..1780a20 100644 --- a/stacks/gcp/GcpStack.ts +++ b/stacks/gcp/GcpStack.ts @@ -22,7 +22,7 @@ import { vpcAccessConnector, cloudRunServiceIamMember, } from "../../providers/google"; -import { provider as archiveProvider, dataArchiveFile } from "@cdktf/provider-archive"; +import { provider as archiveProvider, dataArchiveFile } from "../../providers/archive"; import { StackOptions, GcpFunction } from "./types"; export default class GcpStack extends TerraformStack { From c87b00d81d093ac022b7b8b0d3ea1e5b537347dd Mon Sep 17 00:00:00 2001 From: Tomas Gerulaitis Date: Fri, 24 Jul 2026 16:26:41 +0100 Subject: [PATCH 3/3] Bump package version --- CHANGELOG.md | 17 +++++++++++++++++ package.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6f5eea..26b7aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.2.0](https://github.com/Space48/cloud-seed/compare/v5.1.0...v5.2.0) + +### Added + +- Google provider bindings are now exported as @space48/cloud-seed/providers/google +- Archive provider bindings are now exported as @space48/cloud-seed/providers/archive + +### Changed + +- Replaced prebuilt @cdktf/provider-google and @cdktf/provider-archive providers, which were no longer supported, with locally generated bindings +- Google provider upgraded to 7.41.0 +- Archive provider upgraded to 2.8.0 + +### Fixed + +- Fixed functions retaining their direct VPC egress configuration after the vpc configuration is removed in runtimeConfig + ## [5.1.0](https://github.com/Space48/cloud-seed/compare/v5.0.2...v5.1.0) ### Added diff --git a/package.json b/package.json index 750cede..d523d73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@space48/cloud-seed", - "version": "5.1.0", + "version": "5.2.0", "description": "Cloud infrastructure automation tool that uses Terraform CDK.", "main": "dist/index.js", "exports": {