diff --git a/prepare-labs/README.md b/prepare-labs/README.md index 7e44a22e..97875f91 100644 --- a/prepare-labs/README.md +++ b/prepare-labs/README.md @@ -66,7 +66,7 @@ Here is where we look for credentials for each provider: - Civo: CLI configuration file (`~/.civo.json`) - Digital Ocean: CLI configuration file (`~/.config/doctl/config.yaml`) - Exoscale: CLI configuration file (`~/.config/exoscale/exoscale.toml`) -- Google Cloud: FIXME, note that the project name is currently hard-coded to `prepare-tf` +- Google Cloud: we're using "Application Default Credentials (ADC)"; run `gcloud auth application-default login`; note that we'll use the default "project" set in `gcloud` unless you set the `GOOGLE_PROJECT` environment variable - Hetzner: CLI configuration file (`~/.config/hcloud/cli.toml`) - Linode: CLI configuration file (`~/.config/linode-cli`) - OpenStack: you will need to write a tfvars file (check [that exemple](terraform/virtual-machines/openstack/tfvars.example)) diff --git a/prepare-labs/lib/commands.sh b/prepare-labs/lib/commands.sh index 255c13bf..a448e295 100644 --- a/prepare-labs/lib/commands.sh +++ b/prepare-labs/lib/commands.sh @@ -270,7 +270,27 @@ _cmd_create() { ln -s ../../$SETTINGS tags/$TAG/settings.env.orig cp $SETTINGS tags/$TAG/settings.env - . $SETTINGS + + # For Google Cloud, it is necessary to specify which "project" to use. + # Unfortunately, the Terraform provider doesn't seem to have a way + # to detect which Google Cloud project you want to use; it has to be + # specified one way or another. Let's decide that it should be set with + # the GOOGLE_PROJECT env var; and if that var is not set, we'll try to + # figure it out from gcloud. + # (See https://github.com/hashicorp/terraform-provider-google/issues/10907#issuecomment-1015721600) + # Since we need that variable to be set each time we'll call Terraform + # (e.g. when destroying the environment), let's save it to the settings.env + # file. + if [ "$PROVIDER" = "googlecloud" ]; then + if ! [ "$GOOGLE_PROJECT" ]; then + info "PROVIDER=googlecloud but GOOGLE_PROJECT is not set. Detecting it." + GOOGLE_PROJECT=$(gcloud config get project) + info "GOOGLE_PROJECT will be set to '$GOOGLE_PROJECT'." + fi + echo "export GOOGLE_PROJECT=$GOOGLE_PROJECT" >> tags/$TAG/settings.env + fi + + . tags/$TAG/settings.env echo $MODE > tags/$TAG/mode echo $PROVIDER > tags/$TAG/provider @@ -1218,14 +1238,17 @@ fi " } -_cmd ssh "Open an SSH session to the first node of a tag" +_cmd ssh "Open an SSH session to a node (first one by default)" _cmd_ssh() { TAG=$1 need_tag - IP=$(head -1 tags/$TAG/ips.txt) - info "Logging into $IP (default password: $USER_PASSWORD)" - ssh $SSHOPTS $USER_LOGIN@$IP - + if [ "$2" ]; then + ssh -l ubuntu -i tags/$TAG/id_rsa $2 + else + IP=$(head -1 tags/$TAG/ips.txt) + info "Logging into $IP (default password: $USER_PASSWORD)" + ssh $SSHOPTS $USER_LOGIN@$IP + fi } _cmd tags "List groups of VMs known locally" diff --git a/prepare-labs/lib/pssh.sh b/prepare-labs/lib/pssh.sh index 7110a9fc..6a43bfa3 100644 --- a/prepare-labs/lib/pssh.sh +++ b/prepare-labs/lib/pssh.sh @@ -23,6 +23,14 @@ pssh() { # necessary - or down to zero, too. sleep ${PSSH_DELAY_PRE-1} + # When things go wrong, it's convenient to ask pssh to show the output + # of the failed command. Let's make that easy with a DEBUG env var. + if [ "$DEBUG" ]; then + PSSH_I=-i + else + PSSH_I="" + fi + $(which pssh || which parallel-ssh) -h $HOSTFILE -l ubuntu \ --par ${PSSH_PARALLEL_CONNECTIONS-100} \ --timeout 300 \ @@ -31,5 +39,6 @@ pssh() { -O UserKnownHostsFile=/dev/null \ -O StrictHostKeyChecking=no \ -O ForwardAgent=yes \ + $PSSH_I \ "$@" } diff --git a/prepare-labs/terraform/one-kubernetes/googlecloud/locals.tf b/prepare-labs/terraform/one-kubernetes/googlecloud/locals.tf deleted file mode 100644 index aeb06c4f..00000000 --- a/prepare-labs/terraform/one-kubernetes/googlecloud/locals.tf +++ /dev/null @@ -1,12 +0,0 @@ -locals { - location = var.location != null ? var.location : "europe-north1-a" - region = replace(local.location, "/-[a-z]$/", "") - # Unfortunately, the following line doesn't work - # (that attribute just returns an empty string) - # so we have to hard-code the project name. - #project = data.google_client_config._.project - project = "prepare-tf" -} - -data "google_client_config" "_" {} - diff --git a/prepare-labs/terraform/one-kubernetes/googlecloud/main.tf b/prepare-labs/terraform/one-kubernetes/googlecloud/main.tf index 605944ea..bf6ca1aa 100644 --- a/prepare-labs/terraform/one-kubernetes/googlecloud/main.tf +++ b/prepare-labs/terraform/one-kubernetes/googlecloud/main.tf @@ -1,7 +1,7 @@ resource "google_container_cluster" "_" { - name = var.cluster_name - project = local.project - location = local.location + name = var.cluster_name + location = local.location + deletion_protection = false #min_master_version = var.k8s_version # To deploy private clusters, uncomment the section below, @@ -42,7 +42,7 @@ resource "google_container_cluster" "_" { node_pool { name = "x86" node_config { - tags = var.common_tags + tags = ["lab-${var.cluster_name}"] machine_type = local.node_size } initial_node_count = var.min_nodes_per_pool @@ -62,3 +62,25 @@ resource "google_container_cluster" "_" { } } } + +resource "google_compute_firewall" "_" { + name = "lab-${var.cluster_name}" + network = "default" + + allow { + protocol = "tcp" + ports = ["0-65535"] + } + + allow { + protocol = "udp" + ports = ["0-65535"] + } + + allow { + protocol = "icmp" + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["lab-${var.cluster_name}"] +} diff --git a/prepare-labs/terraform/one-kubernetes/googlecloud/outputs.tf b/prepare-labs/terraform/one-kubernetes/googlecloud/outputs.tf index 68794346..f116f653 100644 --- a/prepare-labs/terraform/one-kubernetes/googlecloud/outputs.tf +++ b/prepare-labs/terraform/one-kubernetes/googlecloud/outputs.tf @@ -6,6 +6,8 @@ output "has_metrics_server" { value = true } +data "google_client_config" "_" {} + output "kubeconfig" { sensitive = true value = <<-EOT diff --git a/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf b/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf deleted file mode 100644 index 53fca6a2..00000000 --- a/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf +++ /dev/null @@ -1,8 +0,0 @@ -terraform { - required_providers { - google = { - source = "hashicorp/google" - version = "4.5.0" - } - } -} diff --git a/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf b/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf new file mode 120000 index 00000000..109a58b4 --- /dev/null +++ b/prepare-labs/terraform/one-kubernetes/googlecloud/provider.tf @@ -0,0 +1 @@ +../../providers/googlecloud/provider.tf \ No newline at end of file diff --git a/prepare-labs/terraform/providers/googlecloud/provider.tf b/prepare-labs/terraform/providers/googlecloud/provider.tf new file mode 100644 index 00000000..d17478a3 --- /dev/null +++ b/prepare-labs/terraform/providers/googlecloud/provider.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "~> 7.0" + } + } +} diff --git a/prepare-labs/terraform/providers/googlecloud/variables.tf b/prepare-labs/terraform/providers/googlecloud/variables.tf index cb126c89..08115f82 100644 --- a/prepare-labs/terraform/providers/googlecloud/variables.tf +++ b/prepare-labs/terraform/providers/googlecloud/variables.tf @@ -9,5 +9,9 @@ variable "node_sizes" { variable "location" { type = string - default = null + default = "europe-north1-a" } + +locals { + location = (var.location != "" && var.location != null) ? var.location : "europe-north1-a" +} \ No newline at end of file diff --git a/prepare-labs/terraform/virtual-machines/googlecloud/common.tf b/prepare-labs/terraform/virtual-machines/googlecloud/common.tf new file mode 120000 index 00000000..a0251abd --- /dev/null +++ b/prepare-labs/terraform/virtual-machines/googlecloud/common.tf @@ -0,0 +1 @@ +../common.tf \ No newline at end of file diff --git a/prepare-labs/terraform/virtual-machines/googlecloud/config.tf b/prepare-labs/terraform/virtual-machines/googlecloud/config.tf new file mode 120000 index 00000000..a5effb1d --- /dev/null +++ b/prepare-labs/terraform/virtual-machines/googlecloud/config.tf @@ -0,0 +1 @@ +../../providers/googlecloud/config.tf \ No newline at end of file diff --git a/prepare-labs/terraform/virtual-machines/googlecloud/main.tf b/prepare-labs/terraform/virtual-machines/googlecloud/main.tf new file mode 100644 index 00000000..24bc9be1 --- /dev/null +++ b/prepare-labs/terraform/virtual-machines/googlecloud/main.tf @@ -0,0 +1,54 @@ +# Note: names and tags on GCP have to match a specific regex: +# (?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?) +# In other words, they must start with a letter; and generally, +# we make them start with a number (year-month-day-etc, so 2025-...) +# so we prefix names and tags with "lab-" in this configuration. + +resource "google_compute_instance" "_" { + for_each = local.nodes + zone = var.location + name = "lab-${each.value.node_name}" + tags = ["lab-${var.tag}"] + machine_type = each.value.node_size + boot_disk { + initialize_params { + image = "ubuntu-os-cloud/ubuntu-2404-lts-amd64" + } + } + network_interface { + network = "default" + access_config {} + } + metadata = { + "ssh-keys" = "ubuntu:${tls_private_key.ssh.public_key_openssh}" + } +} + +locals { + ip_addresses = { + for key, value in local.nodes : + key => google_compute_instance._[key].network_interface[0].access_config[0].nat_ip + } +} + +resource "google_compute_firewall" "_" { + name = "lab-${var.tag}" + network = "default" + + allow { + protocol = "tcp" + ports = ["0-65535"] + } + + allow { + protocol = "udp" + ports = ["0-65535"] + } + + allow { + protocol = "icmp" + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["lab-${var.tag}"] +} diff --git a/prepare-labs/terraform/virtual-machines/googlecloud/provider.tf b/prepare-labs/terraform/virtual-machines/googlecloud/provider.tf new file mode 120000 index 00000000..109a58b4 --- /dev/null +++ b/prepare-labs/terraform/virtual-machines/googlecloud/provider.tf @@ -0,0 +1 @@ +../../providers/googlecloud/provider.tf \ No newline at end of file diff --git a/prepare-labs/terraform/virtual-machines/googlecloud/variables.tf b/prepare-labs/terraform/virtual-machines/googlecloud/variables.tf new file mode 120000 index 00000000..0591bcae --- /dev/null +++ b/prepare-labs/terraform/virtual-machines/googlecloud/variables.tf @@ -0,0 +1 @@ +../../providers/googlecloud/variables.tf \ No newline at end of file