modules/scripts/startup-script/variables.tf (235 lines of code) (raw):

/** * Copyright 2023 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 = "Project in which the HPC deployment will be created" type = string } variable "deployment_name" { description = "Name of the HPC deployment, used to name GCS bucket for startup scripts." type = string } variable "region" { description = "The region to deploy to" type = string } variable "gcs_bucket_path" { description = "The GCS path for storage bucket and the object, starting with `gs://`." type = string default = null } variable "bucket_viewers" { description = "Additional service accounts or groups, users, and domains to which to grant read-only access to startup-script bucket (leave unset if using default Compute Engine service account)" type = list(string) default = [] validation { condition = alltrue([ for u in var.bucket_viewers : length(regexall("^(allUsers$|allAuthenticatedUsers$|user:|group:|serviceAccount:|domain:)", u)) > 0 ]) error_message = "Bucket viewer members must begin with user/group/serviceAccount/domain following https://cloud.google.com/iam/docs/reference/rest/v1/Policy#Binding" } } variable "debug_file" { description = "Path to an optional local to be written with 'startup_script'." type = string default = null } variable "labels" { description = "Labels for the created GCS bucket. Key-value pairs." type = map(string) } variable "runners" { description = <<EOT List of runners to run on remote VM. Runners can be of type ansible-local, shell or data. A runner must specify one of 'source' or 'content'. All runners must specify 'destination'. If 'destination' does not include a path, it will be copied in a temporary folder and deleted after running. Runners may also pass 'args', which will be passed as argument to shell runners only. EOT type = list(map(string)) validation { condition = alltrue([ for r in var.runners : contains(keys(r), "type") ]) error_message = "All runners must declare a type." } validation { condition = alltrue([ for r in var.runners : contains(keys(r), "destination") ]) error_message = "All runners must declare a destination name (even without a path)." } validation { condition = length(distinct([for r in var.runners : r["destination"]])) == length(var.runners) error_message = "All startup-script runners must have a unique destination." } validation { condition = alltrue([ for r in var.runners : r["type"] == "ansible-local" || r["type"] == "shell" || r["type"] == "data" ]) error_message = "The 'type' must be 'ansible-local', 'shell' or 'data'." } # this validation tests that exactly 1 or other of source/content have been # set to anything (including null) validation { condition = alltrue([ for r in var.runners : can(r["content"]) != can(r["source"]) ]) error_message = "A runner must specify either 'content' or 'source', but never both." } # this validation tests that at least 1 of source/content are non-null # can fail either by not having been set all or by being set to null validation { condition = alltrue([ for r in var.runners : lookup(r, "content", lookup(r, "source", null)) != null ]) error_message = "A runner must specify a non-null 'content' or 'source'." } default = [] } variable "docker" { description = "Install and configure Docker" type = object({ enabled = optional(bool, false) world_writable = optional(bool, false) daemon_config = optional(string, "") }) default = { enabled = false } validation { condition = !coalesce(var.docker.world_writable) || var.docker.enabled error_message = "var.docker.world_writable should only be set if var.docker.enabled is set to true" } validation { condition = !can(coalesce(var.docker.daemon_config)) || var.docker.enabled error_message = "var.docker.daemon_config should only be set if var.docker.enabled is set to true" } validation { condition = !can(coalesce(var.docker.daemon_config)) || can(jsondecode(var.docker.daemon_config)) error_message = "var.docker.daemon_config should be set to a valid Docker daemon JSON configuration" } } # tflint-ignore: terraform_unused_declarations variable "enable_docker_world_writable" { description = "DEPRECATED: use var.docker" type = bool default = null validation { condition = var.enable_docker_world_writable == null error_message = "The variable enable_docker_world_writable has been removed. Use var.docker instead" } } # tflint-ignore: terraform_unused_declarations variable "install_docker" { description = "DEPRECATED: use var.docker." type = bool default = null validation { condition = var.install_docker == null error_message = "The variable install_docker has been removed. Use var.docker instead" } } variable "local_ssd_filesystem" { description = "Create and mount a filesystem from local SSD disks (data will be lost if VMs are powered down without enabling migration); enable by setting mountpoint field to a valid directory path." type = object({ fs_type = optional(string, "ext4") mountpoint = optional(string, "") permissions = optional(string, "0755") }) validation { condition = can(coalesce(var.local_ssd_filesystem.fs_type)) error_message = "var.local_ssd_filesystem.fs_type must be set to a filesystem supported by the Linux distribution." } validation { condition = var.local_ssd_filesystem.mountpoint == "" || startswith(var.local_ssd_filesystem.mountpoint, "/") error_message = "To enable local SSD filesystems, var.local_ssd_filesystem.mountpoint must be set to an absolute path to a mountpoint." } validation { condition = length(regexall("^[0-7]{3,4}$", var.local_ssd_filesystem.permissions)) > 0 error_message = "The POSIX permissions for the mountpoint must be represented as a 3 or 4-digit octal" } default = { fs_type = "ext4" mountpoint = "" permissions = "0755" } nullable = false } variable "install_cloud_ops_agent" { description = "Warning: Consider using `install_stackdriver_agent` for better performance. Run Google Ops Agent installation script if set to true." type = bool default = false } variable "install_stackdriver_agent" { description = "Run Google Stackdriver Agent installation script if set to true. Preferred over ops agent for performance." type = bool default = false } variable "install_ansible" { description = "Run Ansible installation script if either set to true or unset and runner of type 'ansible-local' are used." type = bool default = null } variable "configure_ssh_host_patterns" { description = <<EOT If specified, it will automate ssh configuration by: - Defining a Host block for every element of this variable and setting StrictHostKeyChecking to 'No'. Ex: "hpc*", "hpc01*", "ml*" - The first time users log-in, it will create ssh keys that are added to the authorized keys list This requires a shared /home filesystem and relies on specifying the right prefix. EOT type = list(string) default = [] } # tflint-ignore: terraform_unused_declarations variable "prepend_ansible_installer" { description = <<EOT DEPRECATED. Use `install_ansible=false` to prevent ansible installation. EOT type = bool default = null validation { condition = var.prepend_ansible_installer == null error_message = "The variable prepend_ansible_installer has been removed. Use install_ansible instead" } } variable "ansible_virtualenv_path" { description = "Virtual environment path in which to install Ansible" type = string default = "/usr/local/ghpc-venv" validation { condition = can(regex("^(/[\\w-]+)+$", var.ansible_virtualenv_path)) error_message = "var.ansible_virtualenv_path must be an absolute path to a directory without spaces or special characters" } } variable "http_proxy" { description = "Web (http and https) proxy configuration for pip, apt, and yum/dnf and interactive shells" type = string default = "" nullable = false } variable "http_no_proxy" { description = "Domains for which to disable http_proxy behavior. Honored only if var.http_proxy is set" type = string default = ".google.com,.googleapis.com,metadata.google.internal,localhost,127.0.0.1" nullable = false } variable "install_cloud_rdma_drivers" { description = "If true, will install and reload Cloud RDMA drivers. Currently only supported on Rocky Linux 8." type = bool default = false } variable "set_ofi_cloud_rdma_tunables" { description = "Controls whether to enable specific OFI environment variables for workloads using Cloud RDMA networking. Should be false for non-RDMA workloads." type = bool default = false }