# click-to-deploy: the source behind Google Cloud Marketplace solutions

> The click-to-deploy repository holds the deployment source for the solutions listed on Google Cloud Marketplace, in three shapes: container images, Kubernetes applications, and virtual machine images built from Chef cookbooks. Each shape has its own Cloud Build configuration, and the README keeps an up to date table of the solutions still carrying the log4j CVEs.

**GoogleCloudPlatform/click-to-deploy** — Source for Google Click to Deploy solutions listed on Google Cloud Marketplace.

- Repository: https://github.com/GoogleCloudPlatform/click-to-deploy
- Stars: 773 · Forks: 464
- Language: Python
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/googlecloudplatform-click-to-deploy

## The source behind the marketplace button

The click-to-deploy repository holds the source for the Google Click to Deploy solutions that are listed on Google Cloud Marketplace. That is the entire scope, and the repository description is explicit about it.

The name refers to the deployment model it supports. A Click to Deploy listing in the marketplace is a button that provisions a working application in a Google Cloud project, and the point of this repository is that the machinery behind that button is readable, in your own repository, rather than hidden inside a proprietary pipeline.

That is a useful thing to have for several kinds of reader. Someone evaluating a marketplace listing can see the deployment scripts, the configuration, and the application definitions rather than taking the listing on trust. Someone who wants to modify a solution can fork the source and adapt it. And someone who has already clicked the button and now wants to maintain the result can see what was created, which is not always obvious from the resulting infrastructure alone.

The repository is Apache 2.0 licensed, its primary language is Python, the default branch is master, and the last push was on 2026-10-15. There are no GitHub releases, which is consistent with a set of deployment definitions rather than a distributable artifact.

The top level of the tree shows the three kinds of solution immediately. There are docker and k8s directories with their own Dockerfiles at the root, named docker.Dockerfile and k8s.Dockerfile, a vm directory for the virtual machine shape, a scripts directory holding the Python, a tools directory, a triggers directory, and five Cloud Build configuration files.

The licence file, the contributing guide, and a Makefile that wires the local checks together complete the picture of a repository that expects people to work in it.

## Three shapes of solution, five build configurations

The solutions come in three kinds, and each one needs a different deployment mechanism, which is why the repository splits three ways.

The docker directory holds the container image solutions, and the k8s directory holds the Kubernetes applications, deployed into a GKE cluster. The vm directory holds the virtual machine solutions, and the build tooling there is different in kind, because a virtual machine image is assembled with a configuration management tool rather than from a container base image. The Makefile reveals that tool, since the lint target mounts the vm/chef directory into a Chef Workstation container and runs cookstyle over the cookbooks, and a separate run mounts vm/tests/solutions and runs cookstyle over the test suites.

So the VM solutions are Chef cookbooks, with a test directory of solution definitions alongside them, and the container and Kubernetes solutions are the other two shapes.

Continuous integration uses Cloud Build, and the README says each type of application has its own configuration file. The five configuration files at the root match that description: cloudbuild-docker.yaml, cloudbuild-k8s.yaml, and cloudbuild-vm.yaml for the three shapes, plus cloudbuild-dispatcher.yaml, which appears to be the piece that routes a change to the right pipeline, and cloudbuild-triggers-check.yaml, which checks the trigger configuration itself.

The README links to the per-area documentation for the details, with the Cloud Build section in the docker, k8s, and vm readmes respectively. That split documentation is the practical navigation for anyone modifying one shape of solution without touching the others.

## The log4j table is the honest part of the README

There is a section about log4j vulnerabilities, and it is the most useful thing in this README for anyone considering one of these solutions.

The framing is that the project is constantly working on updating the scripts used in the repository to use non-impacted versions of the open source software used here, so updates are constantly being made. And then there is the list of the solutions that are currently affected by the log4j CVEs, or that are using a log4j version older than 2.16.

The virtual machine table lists elasticsearch, logstash, magento, sonarqube, and liferay, with magento and sonarqube marked as vulnerable because they use elasticsearch, and liferay marked as vulnerable on its own.

The Kubernetes table lists activemq, elastic-gke-logging, elasticsearch, kafka, magento, sonarqube, and zookeeper, with activemq and kafka noted as using log4j 1.x, and elastic-gke-logging, elasticsearch, magento, sonarqube, and zookeeper marked as vulnerable, several of them because they use elasticsearch.

Two things are worth drawing from those tables. The first is that the affected set is not a single application but a shared dependency, since a solution that embeds elasticsearch inherits the problem, and that is why eight Kubernetes solutions are listed for four root causes. The second is that the tables are dated by their content rather than by a version, and the note says the updates are constant, so the list in a given checkout is a snapshot.

The practical advice is plain. If you are evaluating one of these solutions, check whether it appears in either table before you deploy it, and if it does, find out what the current version of the underlying component is rather than assuming the listing is maintained in step with the fix. A marketplace listing that provisions an application for you does not necessarily provision a patched one, and this README is the place that tells you so.

## Custom worker pools, and the gcloud command that creates one

The Cloud Build configurations use Google Cloud Build custom worker pools, which is a detail that catches people out the first time they run a build, because a worker pool is something you have to create in the project before the pipeline can use it.

The README gives the command that creates one.

```bash
gcloud beta builds worker-pools create gcb-workers-pool-e2 \
  --project=[PROJECT_ID] \
  --peered-network=projects/[NETWORK_PROJECT_NUMBER]/global/networks/default \
  --region=us-central1 \
  --worker-machine-type=e2-standard-2
```

The two placeholders are spelled out afterwards. The project ID is the GCP project where you want to create the pool, and the network project number is the project number of the Cloud project that holds your VPC network.

Two details in the command are worth noticing. The pool is peered to a specific network, and the network is referenced by project number rather than by name, which is a small but real difference in how you have to know your own infrastructure. And the region is given explicitly, so the pool is regional, which means the Cloud Build configuration has to name the same region or the build will not find the pool.

The machine type is e2-standard-2, which is a modest worker, and that is worth comparing against what your builds actually need, because the builds here assemble images and cookbooks rather than compiling large codebases.

The command is still in beta, which the README reflects by using the gcloud beta prefix, and it points at the gcloud beta builds worker-pools reference for the full set of options.

## The Makefile, and the three local checks it wraps

The Makefile is the entry point for working in the repository locally, and it does three things.

The first is the Python tests, run with the standard library test runner rather than with pytest, discovering test files under the scripts directory with a pattern.

```bash
python-test: ## Runs tests for Python scripts
	@python --version
	@python -m unittest discover -s scripts -p "*_test.py"
```

The second is the Chef lint, and it is the most interesting target, because it runs the linter inside the same container image that would be used to build the cookbooks. Three separate cookstyle invocations happen: one to print the version, one over the cookbooks themselves with the vm/chef directory mounted read only, and one over the test solutions with the vm/tests directory mounted read only. Running the lint in the tool's own image is the difference between a lint that matches the build and one that does not.

```bash
vm-lint: ## Runs lint for Chef cookbooks
	@docker pull chef/chefworkstation
	# cookstyle print version
	@docker run --rm --entrypoint cookstyle -v $(PWD)/vm/chef:/chef:ro chef/chefworkstation --version
	# cookstyle on cookbooks
	@docker run --rm --entrypoint cookstyle -v $(PWD)/vm/chef:/chef:ro chef/chefworkstation /chef/cookbooks
	# cookstyle on tests
	@docker run --rm --entrypoint cookstyle -v $(PWD)/vm/tests:/tests:ro chef/chefworkstation /tests/solutions
```

The third is trigger generation, which produces the Cloud Build triggers for the virtual machine solutions by running a Python script from the scripts directory.

```bash
vm-generate-triggers: ## Generates and displays GCB triggers for VM
	@python scripts/triggers_vm_generator.py
```

The help target prints the available targets with their descriptions, and the file carries a TODO from one of the maintainers about invoking the targets into the container, which suggests the Docker invocations are on the way to being unified.

The trigger generator is the one to understand before you touch the pipelines. The triggers live in a directory at the top level, and generating them rather than editing them by hand is what keeps a change to a solution and a change to its build trigger in step.

## Not an officially supported product

The second section of the README is a disclaimer, and it is short: this is not an officially supported Google product.

That sentence sits directly under the description, before anything else, and it shapes how the whole repository should be read. A Click to Deploy listing in the Cloud Marketplace is a supported deployment path. The source behind it, in this repository, is not the same thing, and the difference is not cosmetic.

In practice it means a few things. You are reading the deployment definitions rather than a support contract, so a change in behaviour can land in the repository without the kind of notice and compatibility promise that comes with a supported product. The Cloud Build configurations reference custom worker pools and a specific network peering model, which is infrastructure you are expected to have and to understand. And the trigger generation step produces real build triggers for real projects, which is a thing to be careful with on a first run.

It also means the log4j tables should be read as the primary information rather than as a footnote. An unsupported repository with a published list of solutions still carrying a known vulnerable dependency is telling you exactly what you need to know before you click, and that transparency is the most valuable thing here.

For a team that wants to use one of these solutions in production, the sensible approach follows from all of that. Read the source for the solution you intend to use, check the vulnerability tables, generate and review the triggers before connecting them, and treat the repository as the starting point for something you then own.

## Conclusion

click-to-deploy fits a team that wants to see exactly how a Marketplace one click deployment is wired, whether to reuse a solution, to fork a cookbook or a Kubernetes manifest, or to understand what the automation actually does before clicking the button. It does not fit a team looking for a supported Google product, because the README states plainly that it is not one, and it does not fit anyone who intends to run the log4j affected solutions unchanged, since several of them are still listed as vulnerable in the README. Verify first which of the solutions you plan to deploy appears in the vulnerability tables, that the Cloud Build worker pool your configuration expects exists in the project and region you are pointing it at, and that the trigger generation step in the Makefile produces the build triggers you expect before you wire them into a real pipeline.

## FAQ

### What is the click-to-deploy repository?

It holds the source for the Google Click to Deploy solutions listed on Google Cloud Marketplace, in three shapes: container images under docker, Kubernetes applications under k8s, and virtual machine solutions under vm. It is Apache 2.0 licensed and, by its own disclaimer, not an officially supported Google product.

### Which click-to-deploy solutions are still affected by the log4j CVEs?

The README keeps two tables. For virtual machines: elasticsearch, logstash, magento, sonarqube, and liferay. For Kubernetes applications: activemq, elastic-gke-logging, elasticsearch, kafka, magento, sonarqube, and zookeeper, several of them because they use elasticsearch.

### How do I run the local checks in the click-to-deploy repository?

Through the Makefile. The python-test target runs the standard library test discovery over the scripts directory, vm-lint runs cookstyle inside the Chef Workstation container over the cookbooks and the test solutions, and vm-generate-triggers runs the Python generator that produces the Cloud Build triggers.

### Why do the click-to-deploy Cloud Build builds need a custom worker pool?

The Cloud Build configurations use Google Cloud Build custom worker pools, and the README shows the gcloud beta command that creates one, with the project, the peered network project number, the region, and the machine type. The pool has to exist in the project and region the configuration names before a build can use it.

### What are the three deployment shapes in click-to-deploy?

Container images, Kubernetes applications, and virtual machine solutions. Each has its own Cloud Build configuration file, cloudbuild-docker.yaml, cloudbuild-k8s.yaml, and cloudbuild-vm.yaml, plus a dispatcher and a trigger check configuration, and the virtual machine solutions are built from Chef cookbooks.

## Sources

- [GoogleCloudPlatform/click-to-deploy on GitHub](https://github.com/GoogleCloudPlatform/click-to-deploy)
- [Issues](https://github.com/GoogleCloudPlatform/click-to-deploy/issues)
- [License: Apache-2.0](https://github.com/GoogleCloudPlatform/click-to-deploy/blob/master/LICENSE)
- [README](https://github.com/GoogleCloudPlatform/click-to-deploy/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/googlecloudplatform-click-to-deploy
