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