From a6598c363ae6d446e732c9cf4762143ce16165a3 Mon Sep 17 00:00:00 2001 From: hsmatulisgoogle Date: Mon, 24 Jun 2024 13:57:32 -0400 Subject: [PATCH] feat: Implement new Ops agent policy module (#101) --- .../ops_agent_policy_install_all/README.md | 22 ++ examples/ops_agent_policy_install_all/main.tf | 35 ++ .../ops_agent_policy_install_all/variables.tf | 20 + .../ops_agent_policy_install_all/versions.tf | 26 ++ .../README.md | 23 ++ .../main.tf | 31 ++ .../variables.tf | 24 ++ .../versions.tf | 26 ++ .../README.md | 23 ++ .../main.tf | 26 ++ .../variables.tf | 25 ++ .../versions.tf | 26 ++ modules/ops-agent-policy/README.md | 26 ++ modules/ops-agent-policy/main.tf | 346 ++++++++++++++++++ .../policy_major_version_install.yaml | 326 +++++++++++++++++ modules/ops-agent-policy/metadata.yaml | 82 +++++ modules/ops-agent-policy/outputs.tf | 21 ++ .../policy_pin_to_version_install.yaml | 238 ++++++++++++ .../uninstall/policy_uninstall.yaml | 327 +++++++++++++++++ modules/ops-agent-policy/variables.tf | 77 ++++ modules/ops-agent-policy/versions.tf | 26 ++ 21 files changed, 1776 insertions(+) create mode 100644 examples/ops_agent_policy_install_all/README.md create mode 100644 examples/ops_agent_policy_install_all/main.tf create mode 100644 examples/ops_agent_policy_install_all/variables.tf create mode 100644 examples/ops_agent_policy_install_all/versions.tf create mode 100644 examples/ops_agent_policy_install_all_in_region/README.md create mode 100644 examples/ops_agent_policy_install_all_in_region/main.tf create mode 100644 examples/ops_agent_policy_install_all_in_region/variables.tf create mode 100644 examples/ops_agent_policy_install_all_in_region/versions.tf create mode 100644 examples/ops_agent_policy_install_all_in_zone/README.md create mode 100644 examples/ops_agent_policy_install_all_in_zone/main.tf create mode 100644 examples/ops_agent_policy_install_all_in_zone/variables.tf create mode 100644 examples/ops_agent_policy_install_all_in_zone/versions.tf create mode 100644 modules/ops-agent-policy/README.md create mode 100644 modules/ops-agent-policy/main.tf create mode 100644 modules/ops-agent-policy/major_version_install/policy_major_version_install.yaml create mode 100644 modules/ops-agent-policy/metadata.yaml create mode 100644 modules/ops-agent-policy/outputs.tf create mode 100644 modules/ops-agent-policy/pin_to_version_install/policy_pin_to_version_install.yaml create mode 100644 modules/ops-agent-policy/uninstall/policy_uninstall.yaml create mode 100644 modules/ops-agent-policy/variables.tf create mode 100644 modules/ops-agent-policy/versions.tf diff --git a/examples/ops_agent_policy_install_all/README.md b/examples/ops_agent_policy_install_all/README.md new file mode 100644 index 0000000..273b4e1 --- /dev/null +++ b/examples/ops_agent_policy_install_all/README.md @@ -0,0 +1,22 @@ +# Ops Agent Policy Example + +This example illustrates how to use the `ops-agent-policy` module to install the ops agent on all VMs in a zone. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes | + +## Outputs + +No outputs. + + + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure diff --git a/examples/ops_agent_policy_install_all/main.tf b/examples/ops_agent_policy_install_all/main.tf new file mode 100644 index 0000000..ae6b709 --- /dev/null +++ b/examples/ops_agent_policy_install_all/main.tf @@ -0,0 +1,35 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +provider "google" { + project = var.project_id +} + +data "google_compute_regions" "available" { +} + +data "google_compute_zones" "available" { + for_each = toset(data.google_compute_regions.available.names) + region = each.value +} + +module "ops_agent_policy" { + for_each = toset(flatten([for zones in values(data.google_compute_zones.available) : zones.names])) + source = "../../modules/ops-agent-policy" + assignment_id = "ops-agent-policy-all-in-${each.key}" + zone = each.key + instance_filter = { all = true } +} diff --git a/examples/ops_agent_policy_install_all/variables.tf b/examples/ops_agent_policy_install_all/variables.tf new file mode 100644 index 0000000..561b5a3 --- /dev/null +++ b/examples/ops_agent_policy_install_all/variables.tf @@ -0,0 +1,20 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The ID of the project in which to provision resources." + type = string +} diff --git a/examples/ops_agent_policy_install_all/versions.tf b/examples/ops_agent_policy_install_all/versions.tf new file mode 100644 index 0000000..fc065e8 --- /dev/null +++ b/examples/ops_agent_policy_install_all/versions.tf @@ -0,0 +1,26 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">= 0.13" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.0" + } + } +} diff --git a/examples/ops_agent_policy_install_all_in_region/README.md b/examples/ops_agent_policy_install_all_in_region/README.md new file mode 100644 index 0000000..8f8ae29 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_region/README.md @@ -0,0 +1,23 @@ +# Ops Agent Policy Example + +This example illustrates how to use the `ops-agent-policy` module to install the ops agent on all VMs in a zone. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes | +| region | The region in which to enforce the agent to be installed/uninstalled. | `string` | n/a | yes | + +## Outputs + +No outputs. + + + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure diff --git a/examples/ops_agent_policy_install_all_in_region/main.tf b/examples/ops_agent_policy_install_all_in_region/main.tf new file mode 100644 index 0000000..5aeed66 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_region/main.tf @@ -0,0 +1,31 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +provider "google" { + project = var.project_id +} + +data "google_compute_zones" "available" { + region = var.region +} + +module "ops_agent_policy" { + for_each = toset(data.google_compute_zones.available.names) + source = "../../modules/ops-agent-policy" + assignment_id = "ops-agent-policy-all-in-${each.key}" + zone = each.key + instance_filter = { all = true } +} diff --git a/examples/ops_agent_policy_install_all_in_region/variables.tf b/examples/ops_agent_policy_install_all_in_region/variables.tf new file mode 100644 index 0000000..94e247e --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_region/variables.tf @@ -0,0 +1,24 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The ID of the project in which to provision resources." + type = string +} +variable "region" { + description = "The region in which to enforce the agent to be installed/uninstalled." + type = string +} diff --git a/examples/ops_agent_policy_install_all_in_region/versions.tf b/examples/ops_agent_policy_install_all_in_region/versions.tf new file mode 100644 index 0000000..fc065e8 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_region/versions.tf @@ -0,0 +1,26 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">= 0.13" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.0" + } + } +} diff --git a/examples/ops_agent_policy_install_all_in_zone/README.md b/examples/ops_agent_policy_install_all_in_zone/README.md new file mode 100644 index 0000000..e93a043 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_zone/README.md @@ -0,0 +1,23 @@ +# Ops Agent Policy Example + +This example illustrates how to use the `ops-agent-policy` module to install the ops agent on all VMs in a zone. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes | +| zone | The zone in which to install the ops agent. | `string` | n/a | yes | + +## Outputs + +No outputs. + + + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure diff --git a/examples/ops_agent_policy_install_all_in_zone/main.tf b/examples/ops_agent_policy_install_all_in_zone/main.tf new file mode 100644 index 0000000..197ab95 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_zone/main.tf @@ -0,0 +1,26 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +provider "google" { + project = var.project_id +} + +module "ops_agent_policy" { + source = "../../modules/ops-agent-policy" + assignment_id = "ops-agent-policy-all-in-${var.zone}" + zone = var.zone + instance_filter = { all = true } +} diff --git a/examples/ops_agent_policy_install_all_in_zone/variables.tf b/examples/ops_agent_policy_install_all_in_zone/variables.tf new file mode 100644 index 0000000..c2a492d --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_zone/variables.tf @@ -0,0 +1,25 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The ID of the project in which to provision resources." + type = string +} + +variable "zone" { + description = "The zone in which to install the ops agent." + type = string +} diff --git a/examples/ops_agent_policy_install_all_in_zone/versions.tf b/examples/ops_agent_policy_install_all_in_zone/versions.tf new file mode 100644 index 0000000..fc065e8 --- /dev/null +++ b/examples/ops_agent_policy_install_all_in_zone/versions.tf @@ -0,0 +1,26 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">= 0.13" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 4.0" + } + } +} diff --git a/modules/ops-agent-policy/README.md b/modules/ops-agent-policy/README.md new file mode 100644 index 0000000..d98ab88 --- /dev/null +++ b/modules/ops-agent-policy/README.md @@ -0,0 +1,26 @@ +# Agent Policy + +This module is used to install/uninstall the ops agent in GCE. + +## Usage + +Functional examples are included in the [examples](./../../examples) directory. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| agents\_rule | Whether to install or uninstall the agent, and which version to install. | `object({ package_state : string, version : string })` |
{
"package_state": "installed",
"version": "latest"
}
| no | +| assignment\_id | Resource name. Unique among policy assignments in the given zone | `string` | n/a | yes | +| instance\_filter | Filter to select VMs. Structure is documented below here: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/os_config_os_policy_assignment. |
object({
all : optional(bool),
// excludes a VM if it contains all label-value pairs for some element in the list
exclusion_labels : optional(list(object({
labels : map(string)
})), []),
// includes a VM if it contains all label-value pairs for some element in the list
inclusion_labels : optional(list(object({
labels : map(string)
})), []),
// includes a VM if its inventory data matches at least one of the following inventories
inventories : optional(list(object({
os_short_name : string,
os_version : string
})), []),
})
| n/a | yes | +| project | The ID of the project in which to provision resources. If not present, uses the provider ID | `string` | `null` | no | +| zone | The location to which policy assignments are applied to. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| ops\_agent\_policy | The generated policy for installing/uninstalling the ops agent. | + + diff --git a/modules/ops-agent-policy/main.tf b/modules/ops-agent-policy/main.tf new file mode 100644 index 0000000..09b2692 --- /dev/null +++ b/modules/ops-agent-policy/main.tf @@ -0,0 +1,346 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + is_installed = var.agents_rule.package_state == "installed" + is_pinnned_to_version = length(regexall("2\\.\\d+\\.\\d+", var.agents_rule.version)) > 0 + file_path = (local.is_installed && local.is_pinnned_to_version ? "pin_to_version_install/policy_pin_to_version_install.yaml" : ( + local.is_installed ? "major_version_install/policy_major_version_install.yaml" : ( + "uninstall/policy_uninstall.yaml"))) + file = file("${path.module}/${local.file_path}") + repo_suffix = replace(replace(var.agents_rule.version, ".*.*", ""), "latest", "all") + os_policies = yamldecode(replace(local.file, "$agent_version", local.repo_suffix)) +} + +resource "google_os_config_os_policy_assignment" "ops_agent_policy" { + instance_filter { + all = var.instance_filter.all + dynamic "exclusion_labels" { + for_each = var.instance_filter.exclusion_labels + content { + labels = exclusion_labels.value["labels"] + } + } + dynamic "inclusion_labels" { + for_each = var.instance_filter.inclusion_labels + content { + labels = inclusion_labels.value["labels"] + } + } + dynamic "inventories" { + for_each = var.instance_filter.inventories + content { + os_short_name = inventories.value["os_short_name"] + os_version = inventories.value["os_version"] + } + } + } + location = var.zone + name = var.assignment_id + os_policies { + id = local.os_policies.id + mode = local.os_policies.mode + allow_no_resource_group_match = local.os_policies.allowNoResourceGroupMatch + description = "AUTO-GENERATED VALUE BY TERRAFORM, DO NOT EDIT! Enforces Ops Agent installation state." + + dynamic "resource_groups" { + for_each = local.os_policies.resourceGroups + content { + dynamic "inventory_filters" { + for_each = resource_groups.value.inventoryFilters + content { + os_short_name = inventory_filters.value.osShortName + os_version = try(inventory_filters.value.osVersion, "") + } + } + + dynamic "resources" { + for_each = resource_groups.value.resources + content { + id = resources.value.id + + dynamic "pkg" { + for_each = try(resources.value.pkg[*], []) + content { + desired_state = pkg.value.desiredState + dynamic "apt" { + for_each = try(pkg.value.apt[*], []) + content { + name = apt.value.name + } + } + + dynamic "deb" { + for_each = try(pkg.value.deb[*], []) + content { + source { + + dynamic "remote" { + for_each = try(deb.value.source.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + } + dynamic "gcs" { + for_each = try(deb.value.source.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(deb.value.source.localPath, null) + allow_insecure = try(deb.value.source.allowInsecure, false) + + } + pull_deps = try(deb.value.pullDeps, null) + + } + } + + dynamic "yum" { + for_each = try(pkg.value.yum[*], []) + content { + name = yum.value.name + } + } + + dynamic "zypper" { + for_each = try(pkg.value.zypper[*], []) + content { + name = zypper.value.name + } + } + + dynamic "rpm" { + for_each = try(pkg.value.rpm[*], []) + content { + source { + dynamic "remote" { + for_each = try(rpm.value.source.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + } + dynamic "gcs" { + for_each = try(rpm.value.source.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(rpm.value.source.localPath, null) + allow_insecure = try(rpm.value.source.allowInsecure, false) + } + pull_deps = try(rpm.value.pullDeps, null) + } + } + + dynamic "googet" { + for_each = try(pkg.value.googet[*], []) + content { + name = googet.value.name + } + } + + + dynamic "msi" { + for_each = try(pkg.value.msi[*], []) + content { + source { + dynamic "remote" { + for_each = try(msi.value.source.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + } + dynamic "gcs" { + for_each = try(msi.value.source.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(msi.value.source.localPath, null) + allow_insecure = try(msi.value.source.allowInsecure, false) + } + properties = try(msi.value.properties, null) + } + } + + + } + } + dynamic "repository" { + for_each = try(resources.value.repository[*], []) + content { + dynamic "apt" { + for_each = try(repository.value.apt[*], []) + content { + archive_type = apt.value.archiveType + uri = apt.value.uri + distribution = apt.value.distribution + components = apt.value.components + gpg_key = try(apt.value.gpg_key, null) + } + } + dynamic "yum" { + for_each = try(repository.value.yum[*], []) + content { + id = yum.value.id + display_name = try(yum.value.displayName, null) + base_url = yum.value.baseUrl + gpg_keys = try(yum.value.gpgKeys, null) + } + } + dynamic "zypper" { + for_each = try(repository.value.zypper[*], []) + content { + id = zypper.value.id + display_name = try(zypper.value.displayName, null) + base_url = zypper.value.baseUrl + gpg_keys = try(zypper.value.gpgKeys, null) + } + } + dynamic "goo" { + for_each = try(repository.value.goo[*], []) + content { + name = goo.value.name + url = goo.value.url + } + } + + } + } + dynamic "exec" { + for_each = try(resources.value.exec[*], []) + content { + validate { + dynamic "file" { + for_each = try(exec.value.validate.file[*], []) + content { + dynamic "remote" { + for_each = try(file.value.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + + } + dynamic "gcs" { + for_each = try(file.value.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(file.value.localPath, null) + allow_insecure = try(file.value.allowInsecure, null) + + } + + } + script = try(exec.value.validate.script, null) + args = try(exec.value.validate.args, null) + interpreter = exec.value.validate.interpreter + output_file_path = try(exec.value.validate.outputFilePath, null) + + } + dynamic "enforce" { + for_each = try(exec.value.enforce[*], []) + content { + dynamic "file" { + for_each = try(enforce.value.file[*], []) + content { + dynamic "remote" { + for_each = try(file.value.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + } + dynamic "gcs" { + for_each = try(file.value.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(file.value.localPath, null) + allow_insecure = try(file.value.allowInsecure, null) + + } + } + script = try(enforce.value.script, null) + args = try(enforce.value.args, null) + interpreter = enforce.value.interpreter + output_file_path = try(enforce.value.outputFilePath, null) + } + } + } + } + dynamic "file" { + for_each = try(resources.value.file[*], []) + content { + dynamic "file" { + for_each = try(file.value.file, []) + content { + dynamic "remote" { + for_each = try(file.value.remote[*], []) + content { + uri = remote.value.uri + sha256_checksum = try(remote.value.sha256Checksum, null) + } + } + dynamic "gcs" { + for_each = try(file.value.gcs[*], []) + content { + bucket = gcs.value.bucket + object = gcs.value.object + generation = try(gcs.value.generation, null) + } + } + local_path = try(file.value.localPath, null) + allow_insecure = try(file.value.allowInsecure, null) + } + } + content = try(file.value.content, null) + path = file.value.path + state = file.value.state + } + } + } + } + } + } + } + rollout { + disruption_budget { + percent = 10 + } + min_wait_duration = "3s" + } + description = "AUTO-GENERATED VALUE BY TERRAFORM, DO NOT EDIT! | {\"packageState\":\"${var.agents_rule.package_state}\",\"version\":\"${var.agents_rule.version}\"}'" + project = var.project + skip_await_rollout = true +} diff --git a/modules/ops-agent-policy/major_version_install/policy_major_version_install.yaml b/modules/ops-agent-policy/major_version_install/policy_major_version_install.yaml new file mode 100644 index 0000000..943d007 --- /dev/null +++ b/modules/ops-agent-policy/major_version_install/policy_major_version_install.yaml @@ -0,0 +1,326 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# A template for a single VMM OS policy that installs the given agent major version. +id: goog-ops-agent-policy +mode: ENFORCEMENT +allowNoResourceGroupMatch: true +resourceGroups: +- inventoryFilters: + - osShortName: centos + osVersion: '7' + - osShortName: rhel + osVersion: '7.*' + resources: + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el7-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: centos + osVersion: '8' + - osShortName: rocky + osVersion: '8.*' + - osShortName: rhel + osVersion: '8.*' + resources: + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el8-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: rocky + osVersion: '9.*' + - osShortName: rhel + osVersion: '9.*' + resources: + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el9-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: sles + osVersion: '12.*' + resources: + - id: add-repo + repository: + zypper: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-sles12-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: import-key + exec: + validate: + script: "rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg; rpm --import https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-pkg + pkg: + desiredState: INSTALLED + zypper: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: sles + osVersion: '15.*' + - osShortName: opensuse-leap + osVersion: '15.*' + resources: + - id: add-repo + repository: + zypper: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-sles15-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + zypper: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '10' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-buster-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '11' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bullseye-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '12' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bookworm-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '18.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bionic-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '20.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-focal-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '22.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-jammy-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '23.10' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-mantic-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '24.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-noble-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: INSTALLED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: windows + osVersion: '10.*' + - osShortName: windows + osVersion: '6.*' + resources: + - id: add-repo + repository: + goo: + name: Google Cloud Ops Agent + url: https://packages.cloud.google.com/yuck/repos/google-cloud-ops-agent-windows-$agent_version + - id: install-pkg + pkg: + desiredState: INSTALLED + googet: + name: google-cloud-ops-agent diff --git a/modules/ops-agent-policy/metadata.yaml b/modules/ops-agent-policy/metadata.yaml new file mode 100644 index 0000000..e8de69b --- /dev/null +++ b/modules/ops-agent-policy/metadata.yaml @@ -0,0 +1,82 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: blueprints.cloud.google.com/v1alpha1 +kind: BlueprintMetadata +metadata: + name: terraform-google-cloud-operations + annotations: + config.kubernetes.io/local-config: "true" +spec: + title: Agent Policy + source: + repo: https://github.com/terraform-google-modules/terraform-google-cloud-operations.git + sourceType: git + actuationTool: + type: Terraform + version: '>= 0.13' + examples: + - name: ops_agent_policy_install_all + location: examples/ops_agent_policy_install_all + - name: ops_agent_policy_install_all_in_region + location: examples/ops_agent_policy_install_all_in_region + - name: ops_agent_policy_install_all_in_zone + location: examples/ops_agent_policy_install_all_in_zone + variables: + - name: assignment_id + description: Resource name. Unique among policy assignments in the given zone + type: string + required: true + - name: zone + description: The location to which policy assignments are applied to. + type: string + required: true + - name: project + description: The ID of the project in which to provision resources. If not present, uses the provider ID + type: string + required: false + - name: ops_agent + description: Whether to install or uninstall the agent, and which version to install. + type: "object({package_state: string, version: string})" + required: false + - name: instance_filter + description: "Filter to select VMs. Structure is documented below here: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/os_config_os_policy_assignment" + type: '''object({ + all: optional(bool), + exclusion_labels: optional(list(object({ + labels: map(string) + })), []), + inclusion_labels: optional(list(object({ + labels: map(string) + })), []), + inventories: optional(list(object({ + os_short_name: string, + os_version: string + })), []), + })''' + required: true + + roles: + - level: Project + roles: + - roles/owner + - roles/osconfig.osPolicyAssignmentAdmin + - roles/monitoring.metricWriter + - roles/logging.logWriter + services: + - cloudresourcemanager.googleapis.com + - serviceusage.googleapis.com + - logging.googleapis.com + - monitoring.googleapis.com + - osconfig.googleapis.com diff --git a/modules/ops-agent-policy/outputs.tf b/modules/ops-agent-policy/outputs.tf new file mode 100644 index 0000000..2580b49 --- /dev/null +++ b/modules/ops-agent-policy/outputs.tf @@ -0,0 +1,21 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +output "ops_agent_policy" { + description = "The generated policy for installing/uninstalling the ops agent." + value = google_os_config_os_policy_assignment.ops_agent_policy +} diff --git a/modules/ops-agent-policy/pin_to_version_install/policy_pin_to_version_install.yaml b/modules/ops-agent-policy/pin_to_version_install/policy_pin_to_version_install.yaml new file mode 100644 index 0000000..0954931 --- /dev/null +++ b/modules/ops-agent-policy/pin_to_version_install/policy_pin_to_version_install.yaml @@ -0,0 +1,238 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# A template for a single VMM OS policy that installs the given agent version. +id: goog-ops-agent-policy +mode: ENFORCEMENT +allowNoResourceGroupMatch: true +resourceGroups: +- inventoryFilters: + - osShortName: centos + osVersion: '7' + - osShortName: rhel + osVersion: '7.*' + resources: + - id: install-agent + exec: + validate: + script: "[ $(rpm --query --queryformat '%{VERSION}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: centos + osVersion: '8' + - osShortName: rocky + osVersion: '8.*' + - osShortName: rhel + osVersion: '8.*' + resources: + - id: install-agent + exec: + validate: + script: "[ $(rpm --query --queryformat '%{VERSION}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: rocky + osVersion: '9.*' + - osShortName: rhel + osVersion: '9.*' + resources: + - id: install-agent + exec: + validate: + script: "[ $(rpm --query --queryformat '%{VERSION}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: sles + osVersion: '12.*' + resources: + - id: install-agent + exec: + validate: + script: "[ $(rpm --query --queryformat '%{VERSION}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: sles + osVersion: '15.*' + - osShortName: opensuse-leap + osVersion: '15.*' + resources: + - id: install-agent + exec: + validate: + script: "[ $(rpm --query --queryformat '%{VERSION}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: debian + osVersion: '10' + resources: + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: debian + osVersion: '11' + resources: + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: debian + osVersion: '12' + resources: + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: ubuntu + osVersion: '18.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: ubuntu + osVersion: '20.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: ubuntu + osVersion: '22.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: ubuntu + osVersion: '23.10' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: ubuntu + osVersion: '24.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-agent + exec: + validate: + script: "[ $(dpkg-query --show --showformat '${Version}' 'google-cloud-ops-agent' | cut -d~ -f 1) == '$agent_version' ] && exit 100 || exit 101;" + interpreter: SHELL + enforce: + script: curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh; sudo bash add-google-cloud-ops-agent-repo.sh --also-install --version=$agent_version; + interpreter: SHELL +- inventoryFilters: + - osShortName: windows + osVersion: '10.*' + - osShortName: windows + osVersion: '6.*' + resources: + - id: install-agent + exec: + validate: + script: if (((((googet installed google-cloud-ops-agent) -split ' ')[-1]) -split '@')[0] -eq '$agent_version'){ exit 100; } else { exit 101;} + interpreter: POWERSHELL + enforce: + script: '(New-Object Net.WebClient).DownloadFile("https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.ps1", "${env:UserProfile}\add-google-cloud-ops-agent-repo.ps1"); Invoke-Expression "${env:UserProfile}\add-google-cloud-ops-agent-repo.ps1 -AlsoInstall -Version $agent_version";' + interpreter: POWERSHELL diff --git a/modules/ops-agent-policy/uninstall/policy_uninstall.yaml b/modules/ops-agent-policy/uninstall/policy_uninstall.yaml new file mode 100644 index 0000000..16560a9 --- /dev/null +++ b/modules/ops-agent-policy/uninstall/policy_uninstall.yaml @@ -0,0 +1,327 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# A template for a single VMM OS policy that uninstalls the given agent major version. +id: goog-ops-agent-policy +mode: ENFORCEMENT +allowNoResourceGroupMatch: true +resourceGroups: +- inventoryFilters: + - osShortName: centos + osVersion: '7' + - osShortName: rhel + osVersion: '7.*' + resources: + # TODO: b/329895431 - Consider removing add-repo steps in this policy + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el7-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: centos + osVersion: '8' + - osShortName: rocky + osVersion: '8.*' + - osShortName: rhel + osVersion: '8.*' + resources: + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el8-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: rocky + osVersion: '9.*' + - osShortName: rhel + osVersion: '9.*' + resources: + - id: add-repo + repository: + yum: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-el9-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + yum: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: sles + osVersion: '12.*' + resources: + - id: add-repo + repository: + zypper: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-sles12-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: import-key + exec: + validate: + script: "rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg; rpm --import https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: install-pkg + pkg: + desiredState: REMOVED + zypper: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: sles + osVersion: '15.*' + - osShortName: opensuse-leap + osVersion: '15.*' + resources: + - id: add-repo + repository: + zypper: + id: google-cloud-ops-agent + displayName: Google Cloud Ops Agent Repository + baseUrl: https://packages.cloud.google.com/yum/repos/google-cloud-ops-agent-sles15-x86_64-$agent_version + gpgKeys: + - https://packages.cloud.google.com/yum/doc/yum-key.gpg + - https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + zypper: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '10' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-buster-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '11' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bullseye-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: debian + osVersion: '12' + resources: + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bookworm-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '18.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-bionic-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '20.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-focal-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '22.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-jammy-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '23.10' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-mantic-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: ubuntu + osVersion: '24.04' + resources: + - id: wait-for-cloud-init + exec: + validate: + script: "cloud-init status --wait; exit 100;" + interpreter: SHELL + enforce: + script: "echo hello" + interpreter: SHELL + - id: add-repo + repository: + apt: + archiveType: DEB + uri: https://packages.cloud.google.com/apt + distribution: google-cloud-ops-agent-noble-$agent_version + components: + - main + gpgKey: https://packages.cloud.google.com/apt/doc/apt-key.gpg + - id: install-pkg + pkg: + desiredState: REMOVED + apt: + name: google-cloud-ops-agent +- inventoryFilters: + - osShortName: windows + osVersion: '10.*' + - osShortName: windows + osVersion: '6.*' + resources: + - id: add-repo + repository: + goo: + name: Google Cloud Ops Agent + url: https://packages.cloud.google.com/yuck/repos/google-cloud-ops-agent-windows-$agent_version + - id: install-pkg + pkg: + desiredState: REMOVED + googet: + name: google-cloud-ops-agent diff --git a/modules/ops-agent-policy/variables.tf b/modules/ops-agent-policy/variables.tf new file mode 100644 index 0000000..8b4c2bb --- /dev/null +++ b/modules/ops-agent-policy/variables.tf @@ -0,0 +1,77 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#################################################################### +## Variables for the ops-agent-policy module +#################################################################### + +variable "assignment_id" { + description = "Resource name. Unique among policy assignments in the given zone" + type = string +} + +variable "zone" { + description = "The location to which policy assignments are applied to." + type = string + // Better error message when giving regions instead of zones, + // more validation is done by the underlying API + validation { + condition = length(regexall(".*-.*-.*", var.zone)) > 0 + error_message = "Expected a valid GCP zone" + } +} + +variable "project" { + description = "The ID of the project in which to provision resources. If not present, uses the provider ID" + type = string + default = null +} + +variable "agents_rule" { + description = "Whether to install or uninstall the agent, and which version to install." + type = object({ package_state : string, version : string }) + default = { package_state : "installed", version : "latest" } + validation { + condition = contains(["installed", "removed"], var.agents_rule.package_state) + error_message = "agents_rule.package_state must be one of installed|removed" + } + validation { + condition = (var.agents_rule.version == "latest" || + length(regexall("2\\.\\d+\\.\\d+", var.agents_rule.version)) > 0 || + var.agents_rule.version == "2.*.*") + error_message = "agents_rule.version match one of 'latest', r'2\\.\\d\\.\\d', '2.*.*" + } +} + +variable "instance_filter" { + description = "Filter to select VMs. Structure is documented below here: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/os_config_os_policy_assignment." + type = object({ + all : optional(bool), + // excludes a VM if it contains all label-value pairs for some element in the list + exclusion_labels : optional(list(object({ + labels : map(string) + })), []), + // includes a VM if it contains all label-value pairs for some element in the list + inclusion_labels : optional(list(object({ + labels : map(string) + })), []), + // includes a VM if its inventory data matches at least one of the following inventories + inventories : optional(list(object({ + os_short_name : string, + os_version : string + })), []), + }) +} diff --git a/modules/ops-agent-policy/versions.tf b/modules/ops-agent-policy/versions.tf new file mode 100644 index 0000000..6544cea --- /dev/null +++ b/modules/ops-agent-policy/versions.tf @@ -0,0 +1,26 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">= 0.13" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.0, < 6" + } + } +}