diff --git a/CHANGELOG.md b/CHANGELOG.md
index df42e577f0..5b5fb4b452 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,9 @@ Canonical reference for changes, improvements, and bugfixes for Boundary.
* Introduces soft-delete for users within the client cache.
([PR](https://github.com/hashicorp/boundary/pull/5173)).
+* GCP dynamic host catalog: Add dynamic host catalog support for
+ discovering GCP Compute Engine VM Instances.
+ ([PR](https://github.com/hashicorp/boundary/pull/5229)).
## 0.18.2 (2024/12/12)
### Bug fixes
diff --git a/website/content/docs/concepts/host-discovery/gcp.mdx b/website/content/docs/concepts/host-discovery/gcp.mdx
new file mode 100644
index 0000000000..891e8d1c15
--- /dev/null
+++ b/website/content/docs/concepts/host-discovery/gcp.mdx
@@ -0,0 +1,225 @@
+---
+layout: docs
+page_title: GCP dynamic host catalogs
+description: >-
+ Use dynamic host catalogs to automatically discover GCP Compute Engine VM instances and add them as hosts. Create a host catalog and host set for GCP resources.
+---
+# GCP dynamic host catalogs
+Boundary uses dynamic host catalogs to automatically discover GCP Compute Engine VM instances and add them as hosts.
+
+## Create a host catalog to connect with GCP
+Boundary uses plugins to integrate with a variety of providers. To use
+a dynamic host catalog to integrate with GCP, you create a host catalog of the `plugin` type
+and set the `plugin-name` value to `gcp`. You must also provide the specific
+fields needed for Boundary to authenticate with GCP.
+
+### Authentication with service account
+Create a service account in GCP and download the private key file. The service account should have the following roles:
+- `roles/compute.viewer` (Required): To list Compute Engine VM instance in the project.
+- `roles/iam.serviceAccountKeyAdmin` (Optional): - To rotate the service account key if `disable_credential_rotation` is set to `false`.
+
+Pass the following fields to Boundary for authentication:
+
+
+
+
+```shell-session
+$ boundary host-catalogs create plugin \
+ -scope-id $BOUNDARY_PROJECT_ID \
+ -plugin-name gcp \
+ -attr disable_credential_rotation=true \
+ -attr zone=us-central1-a \
+ -attr project_id=env://GCP_PROJECT_ID \
+ -attr client_email=env://CLIENT_EMAIL \
+ -secret private_key_id=env://PRIVATE_KEY_ID \
+ -secret private_key=file://$PRIVATE_KEY_FILE_PATH
+```
+
+
+
+
+ ```hcl
+ resource "boundary_host_catalog_plugin" "gcp_host_catalog" {
+ name = "GCP Catalog"
+ description = "GCP Host Catalog"
+ scope_id = boundary_scope.project.id
+ plugin_name = "gcp"
+
+ attributes_json = jsonencode({
+ "zone" = "us-central1-a ",
+ "project_id" = var.gcp_project_id,
+ "client_email" = var.gcp_client_email,
+ "disable_credential_rotation" = true })
+ secrets_json = jsonencode({
+ "private_key_id" = var.private_key_id,
+ "private_key" = var.private_key})
+ }
+ ```
+
+
+
+
+### Authentication with service account impersonation
+Service account impersonation allows Boundary to authenticate with GCP using a service account that impersonates another service account.
+Impersonation is useful when you want to restrict the permissions of the service account Boundary uses. Two service accounts are required:
+
+- `Base service account`: The service account Boundary uses to authenticate with GCP. The service account should have the following roles:
+ - `roles/iam.serviceAccountTokenCreator` (Required) - To create a token for the target service account.
+ - `roles/iam.serviceAccountKeyAdmin` (Optional) - To rotate the service account key if `disable_credential_rotation` is set to `false`.
+
+- `Target service account`: The service account to impersonate. The service account should have the following roles:
+ - `roles/compute.viewer` (Required): To list Compute Engine VM instance in the project.
+
+Pass the following fields to Boundary for authentication:
+
+
+
+
+```shell-session
+$ boundary host-catalogs create plugin \
+ -scope-id $BOUNDARY_PROJECT_ID \
+ -plugin-name gcp \
+ -attr disable_credential_rotation=true \
+ -attr zone=us-central1-a \
+ -attr project_id=env://GCP_PROJECT_ID \
+ -attr client_email=env://BASE_SERVICE_ACCOUNT_EMAIL \
+ -attr target_service_account_id=env://TARGET_SERVICE_ACCOUNT_EMAIL \
+ -secret private_key_id=env://BASE_SERVICE_ACCOUNT_PRIVATE_KEY_ID \
+ -secret private_key=file://$BASE_SERVICE_ACCOUNT_PRIVATE_KEY_FILE_PATH
+```
+
+
+
+
+ ```hcl
+ resource "boundary_host_catalog_plugin" "gcp_host_catalog" {
+ name = "GCP Catalog"
+ description = "GCP Host Catalog"
+ scope_id = boundary_scope.project.id
+ plugin_name = "gcp"
+
+ attributes_json = jsonencode({
+ "zone" = "us-central1-a ",
+ "project_id" = var.gcp_project_id,
+ "client_email" = var.gcp_base_service_account_email,
+ "target_service_account_id" = var.gcp_target_service_account_email,
+ "disable_credential_rotation" = true })
+ secrets_json = jsonencode({
+ "private_key_id" = var.base_service_account_private_key_id,
+ "private_key" = var.base_service_account_private_key})
+ }
+ ```
+
+
+
+
+### Authentication with Application Default Credentials (ADC)
+If you run Boundary on a GCP VM instance, you can use Application Default Credentials (ADC) to authenticate with GCP.
+Boundary uses the service account associated with the VM instance to authenticate with GCP.
+
+Pass the following fields to Boundary for authentication:
+
+
+
+
+```shell-session
+$ boundary host-catalogs create plugin \
+ -scope-id $BOUNDARY_PROJECT_ID \
+ -plugin-name gcp \
+ -attr disable_credential_rotation=true \
+ -attr zone=us-central1-a \
+ -attr project_id=env://GCP_PROJECT_ID
+```
+
+
+
+
+ ```hcl
+ resource "boundary_host_catalog_plugin" "gcp_host_catalog" {
+ name = "GCP Catalog"
+ description = "GCP Host Catalog"
+ scope_id = boundary_scope.project.id
+ plugin_name = "gcp"
+
+ attributes_json = jsonencode({
+ "zone" = "us-central1-a ",
+ "project_id" = var.gcp_project_id,
+ "disable_credential_rotation" = true })
+ }
+ ```
+
+
+
+
+The `scope-id` and `plugin-name` fields are required when you create a
+ dynamic host catalog.
+
+The fields following the `attr` and `secret` flags are specific to GCP and are required by
+ Boundary for authentication.
+
+- `zone` (Required): The deployment area within a region. All host sets in this
+ catalog are configured for this zone.
+- `project_id` (Required): The project ID associated with the service account.
+- `disable_credential_rotation` (Optional): When set to `true`, Boundary does not rotate the credentials with GCP automatically.
+- `client_email` (Optional): Boundary uses this email address associated with the service account.
+ The email address used to uniquely identify the service account.
+- `target_service_account_id` (Optional): Boundary uses this email address of the service account to impersonate.
+ This is used for authentication with service account impersonation.
+- `private_key_id` (Optional): The ID of the private key for the service account to use with this host catalog.
+- `private_key` (Optional): The private key for the service account to use with this host catalog.
+
+Refer to [the domain model documentation](/boundary/docs/concepts/domain-model/host-catalogs) for additional fields that you can use when you create host catalogs.
+
+## Create a host set to connect with GCP
+[Host sets](/boundary/docs/concepts/domain-model/host-sets) specify which GCP
+ filters Boundary should use to identify which discovered hosts that should be added as members.
+
+Create a host set using the following command:
+
+
+
+
+```shell-session
+$ boundary host-sets create plugin \
+ -host-catalog-id $BOUNDARY_HOST_CATALOG_ID \
+ -attr filters=labels.env=prod \
+ -attr filters=labels.app=web
+```
+
+
+
+
+```hcl
+resource "boundary_host_set_plugin" "gcp_host_set" {
+ name = "GCP Host Set"
+ description = "GCP Host Set"
+ host_catalog_id = boundary_scope.gcp_host_catalog.id
+ attributes_json = jsonencode({
+ "filters" = ["labels.env=prod", "labels.app=web"] })
+}
+```
+
+
+
+
+The `host-catalog-id` value is a required field that specifies in which host catalog to
+ create this host set.
+
+Like with the host catalog, the fields passed in after the `attr` flag are
+ specific to GCP.
+
+The `filters` field contains string filters in the format key=val1. The key corresponds to
+ a filter option. For a list of filter options, refer to the
+ [GCP API documentation](https://cloud.google.com/compute/docs/reference/rest/v1/instances/list#filter).
+ When you apply multiple filters, the plugin applies a logical `AND` operation to combine the filters.
+
+ If there is no explicit instance status filter, the default status is set to `status="RUNNING"`.
+ This ensures that Boundary only filters running instances, saving time when processing results.
+
+ We recommend using labels as filters because they are more flexible and can filter on multiple values
+ as in the following examples:
+ - `-attr filters=labels.env=dev`
+ - `-attr filters=labels.env=prod AND labels.app=web`
+
+For more fields that you can use when creating host sets, refer to
+ [the domain model documentation](/boundary/docs/concepts/domain-model/host-sets).
diff --git a/website/content/docs/concepts/host-discovery/index.mdx b/website/content/docs/concepts/host-discovery/index.mdx
index 543aa6672c..0b085ad659 100644
--- a/website/content/docs/concepts/host-discovery/index.mdx
+++ b/website/content/docs/concepts/host-discovery/index.mdx
@@ -57,6 +57,9 @@ should be members of the host set.
Boundary currently supports dynamic host catalog for AWS and
Azure and we will continue to grow this ecosystem to support additional providers.
-You can get started with dynamic host catalogs for AWS
-[here](/boundary/tutorials/host-management/aws-host-catalogs)
-and for Azure [here](/boundary/tutorials/host-management/azure-host-catalogs).
+## Next steps
+To get started with dynamic host catalogs, refer to the following topics:
+
+- [AWS dynamic host catalogs](/boundary/docs/concepts/host-discovery/aws)
+- [Azure dynamic host catalogs](/boundary/docs/concepts/host-discovery/azure)
+- [GCP dynamic host catalogs](/boundary/docs/concepts/host-discovery/gcp)
diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json
index 81a02784aa..3034749aec 100644
--- a/website/data/docs-nav-data.json
+++ b/website/data/docs-nav-data.json
@@ -90,7 +90,7 @@
"title": "Architecture",
"routes": [
{
- "title":"System requirements",
+ "title": "System requirements",
"path": "install-boundary/architecture/system-requirements"
},
{
@@ -226,6 +226,10 @@
{
"title": "Azure dynamic hosts",
"path": "concepts/host-discovery/azure"
+ },
+ {
+ "title": "GCP dynamic hosts",
+ "path": "concepts/host-discovery/gcp"
}
]
},
@@ -601,7 +605,7 @@
{
"title": "Connect using a target alias",
"path": "configuration/target-aliases/connect-target-alias"
- },
+ },
{
"title": "Connect using transparent sessions",
"badge": {
@@ -1887,4 +1891,4 @@
}
]
}
-]
+]
\ No newline at end of file