Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7.2.0 - January 16, 2025 #230

Merged
merged 6 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Copyright © 2021-2024, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

ARG TERRAFORM_VERSION=1.8.5
ARG GCP_CLI_VERSION=479.0.0
ARG TERRAFORM_VERSION=1.9.6
ARG GCP_CLI_VERSION=496.0.0

FROM hashicorp/terraform:$TERRAFORM_VERSION as terraform
FROM hashicorp/terraform:$TERRAFORM_VERSION AS terraform
FROM google/cloud-sdk:$GCP_CLI_VERSION-alpine
ARG KUBECTL_VERSION=1.29.7
ARG KUBECTL_VERSION=1.30.6
ARG ENABLE_GKE_GCLOUD_AUTH_PLUGIN=True
ARG INSTALL_COMPONENTS=""

Expand All @@ -18,14 +18,14 @@ COPY . .
RUN apk update \
&& apk upgrade --no-cache \
&& apk add --no-cache jq \
&& curl -sLO https://storage.googleapis.com/kubernetes-release/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl \
&& curl -sLO https://dl.k8s.io/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl \
&& chmod 755 ./kubectl /viya4-iac-gcp/docker-entrypoint.sh \
&& mv ./kubectl /usr/local/bin/kubectl \
&& chmod g=u -R /etc/passwd /etc/group /viya4-iac-gcp \
&& git config --system --add safe.directory /viya4-iac-gcp \
&& terraform init \
&& gcloud components install gke-gcloud-auth-plugin alpha beta cloud-sql-proxy $INSTALL_COMPONENTS \
&& rm -rf /google-cloud-sdk/.install/.backup
&& rm -rf /google-cloud-sdk/.install/.backup \
&& chmod g=u -R /etc/passwd /etc/group /viya4-iac-gcp

ENV TF_VAR_iac_tooling=docker
ENV USE_GKE_GCLOUD_AUTH_PLUGIN=$ENABLE_GKE_GCLOUD_AUTH_PLUGIN
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This project contains Terraform scripts to provision Google Cloud infrastructure
>- Managed Google Kubernetes Engine (GKE) cluster
>- System and User GKE Node pools with required Labels and Taints
>- Infrastructure to deploy SAS Viya platform CAS in SMP or MPP mode
>- Shared Storage options for SAS Viya platform - Google Filestore (ha) or NFS Server (standard)
>- Shared Storage options for SAS Viya platform - Google Filestore (ha), Google NetApp Volumes (ha) or NFS Server (standard)
>- Google Cloud SQL for PostgreSQL instance, optional

[<img src="./docs/images/viya4-iac-gcp-diag.png" alt="Architecture Diagram" width="750"/>](./docs/images/viya4-iac-gcp-diag.png?raw=true)
Expand All @@ -31,10 +31,10 @@ Operational knowledge of

- Terraform or Docker
- #### Terraform
- [Terraform](https://www.terraform.io/downloads.html) - v1.8.5
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl) - v1.29.7
- [jq](https://stedolan.github.io/jq/) - v1.6
- [gcloud CLI](https://cloud.google.com/sdk/gcloud) - (optional - useful as an alternative to the Google Cloud Platform Portal) - v479.0.0
- [Terraform](https://www.terraform.io/downloads.html) - v1.9.6
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl) - v1.30.6
- [jq](https://stedolan.github.io/jq/) - v1.7
- [gcloud CLI](https://cloud.google.com/sdk/gcloud) - (optional - useful as an alternative to the Google Cloud Platform Portal) - v496.0.0
- [gke-gcloud-auth-plugin](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin) - (optional - only for provider based Kubernetes configuration files) - >= v1.26
- #### Docker
- [Docker](https://docs.docker.com/get-docker/)
Expand Down
2 changes: 1 addition & 1 deletion config/sample-input-tf-enterprise.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ create_static_kubeconfig = true
# tags = {} # e.g., { "key1" = "value1", "key2" = "value2" }

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 1
default_nodepool_vm_type = "n2-highmem-8"

Expand Down
29 changes: 23 additions & 6 deletions docs/CONFIG-VARS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Supported configuration variables are listed in the table below. All variables
- [Additional Nodepools](#additional-nodepools)
- [Storage](#storage)
- [For `storage_type=standard` only (NFS server VM)](#for-storage_typestandard-only-nfs-server-vm)
- [For `storage_type=ha` only (Google Filestore)](#for-storage_typeha-only-google-filestore)
- [For `storage_type=ha` with Google Filestore](#for-storage_typeha-with-google-filestore)
- [For `storage_type=ha` with Google NetApp Volumes](#for-storage_typeha-with-google-netapp-volumes)
- [Google Artifact Registry (GAR) and Google Container Registry (GCR)](#google-artifact-registry-gar-and-google-container-registry-gcr)
- [Postgres Servers](#postgres-servers)
- [Monitoring](#monitoring)
Expand Down Expand Up @@ -65,10 +66,11 @@ You can use `default_public_access_cidrs` to set a default range for all created
| gke_subnet_cidr | Address space for the subnet for the GKE resources | string | "192.168.0.0/23" | This variable is ignored when `vpc_name` is set (aka bring your own vnet) |
| gke_pod_subnet_cidr | Secondary address space in the GKE subnet for Kubernetes Pods | string | "10.0.0.0/17" | This variable is ignored when `subnet_names` is set (aka bring your own subnets) |
| gke_service_subnet_cidr | Secondary address space in the GKE subnet for Kubernetes Services | string | "10.1.0.0/22" | This variable is ignored when `subnet_names` is set (aka bring your own subnets) |
| gke_control_plane_subnet_cidr | Address space for the hosted master subnet | string | "10.2.0.0/28" | When providing your own subnets (by setting `subnet_names` make sure your subnets do not overlap this range |
| gke_control_plane_subnet_cidr | Address space for the hosted primary subnet | string | "10.2.0.0/28" | When providing your own subnets (by setting `subnet_names` make sure your subnets do not overlap this range |
| misc_subnet_cidr | Address space for the the auxiliary resources (Jump VM and optionally NFS VM) subnet | string | "192.168.2.0/24" | This variable is ignored when `subnet_names` is set (aka bring your own subnet) |
| filestore_subnet_cidr | Address space for Google Filestore subnet | string | "192.168.3.0/29" | Needs to be at least a /29 range. Only used when `storage_type="ha"` |
| database_subnet_cidr | Address space for Google Cloud SQL Postgres subnet | string | "192.168.4.0/23" | Only used with external postgres |
| netapp_subnet_cidr | Address space for Google Cloud NetApp Volumes subnet | string | "192.168.5.0/24" | Needs to be at least a /24 range. Only used when `storage_type="ha"` and `storage_type_backend="netapp"` |

### Use Existing

Expand Down Expand Up @@ -212,6 +214,7 @@ stateful = {
| Name | Description | Type | Default | Notes |
| :--- | ---: | ---: | ---: | ---: |
| storage_type | Type of Storage. Valid Values: "standard", "ha" | string | "standard" | "standard" creates NFS server VM, "ha" Google Filestore instance |
| storage_type_backend | The storage backend for the chosen `storage_type`. | string | If `storage_type=standard` the default is "nfs";<br>If `storage_type=ha` the default is "filestore" | Valid Values: "nfs" if `storage_type=standard`; "filestore" or "netapp" if `storage_type=ha` |

### For `storage_type=standard` only (NFS server VM)

Expand All @@ -221,13 +224,27 @@ stateful = {
| nfs_vm_admin | OS Admin User for the NFS server VM | string | "nfsuser" | The NFS server VM is only created when storage_type="standard" |
| nfs_raid_disk_size | Size in Gb for each disk of the RAID5 cluster on the NFS server VM | number | 1000 | The NFS server VM is only created when storage_type="standard" |

### For `storage_type=ha` only (Google Filestore)
### For `storage_type=ha` with Google Filestore

| Name | Description | Type | Default | Notes |
| :--- | ---: | ---: | ---: | ---: |
| filestore_tier | The service tier for the Google Filestore Instance | string | "BASIC_HDD" | Valid Values: "BASIC_HDD", "BASIC_SSD" (previously called "STANDARD" and "PREMIUM" respectively.) |
| filestore_size_in_gb | Size in GB of Filesystem in the Google Filestore Instance | number | 1024 for BASIC_HDD, 2560 for BASIC_SDD | 2560 GB is the minimum size for the BASIC_SSD tier. The BASIC_HDD tier allows a minimum size of 1024 GB. |

### For `storage_type=ha` with Google NetApp Volumes

When `storage_type=ha` and `storage_type_backend=netapp` are specified, [Google NetApp Volumes](https://cloud.google.com/netapp/volumes/docs/discover/overview) service is created. Before using this storage option,
- Enable the Google Cloud NetApp Volumes API for your project, see how to enable [here](https://cloud.google.com/netapp/volumes/docs/get-started/configure-access/initiate-console-settings#enable_the_api).
- Grant access to NetApp Volumes operations by granting IAM roles to users. The two predefined roles are `roles/netapp.admin` and `roles/netapp.viewer`. You can assign these roles to specific users or service accounts.
- NetApp Volumes is available in several regions. For details about region availability, see [NetApp Volumes locations](https://cloud.google.com/netapp/volumes/docs/locations).

| Name | Description | Type | Default | Notes |
| :--- | ---: | ---: | ---: | ---: |
| netapp_service_level | The service level of the storage pool. | string | "PREMIUM" | Valid Values are: PREMIUM, EXTREME, STANDARD, FLEX. |
| netapp_protocols | The target volume protocol expressed as a list. | list(string) | ["NFSV3"] | Each value may be one of: NFSV3, NFSV4, SMB. Currently, only NFSV3 is supported by SAS Viya Platform. |
| netapp_capacity_gib | Capacity of the storage pool (in GiB). Storage Pool capacity specified must be between 2048 GiB and 10485760 GiB. | string | "2048" | |
| netapp_volume_path | A unique file path for the volume. Used when creating mount targets. Needs to be unique per location.| string | | |

## Google Artifact Registry (GAR) and Google Container Registry (GCR)

| Name | Description | Type | Default | Notes |
Expand Down Expand Up @@ -267,8 +284,8 @@ Each server element, like `foo = {}`, can contain none, some, or all of the para
| administrator_password | The Password associated with the administrator_login for the PostgreSQL Server | string | "my$up3rS3cretPassw0rd" | |
| server_version | The version of the PostgreSQL server instance | string | "15" | Refer to the [SAS Viya Platform Administration Guide](https://documentation.sas.com/?cdcId=sasadmincdc&cdcVersion=default&docsetId=itopssr&docsetTarget=p05lfgkwib3zxbn1t6nyihexp12n.htm#p1wq8ouke3c6ixn1la636df9oa1u) for the supported versions of PostgreSQL for the SAS Viya platform. |
| ssl_enforcement_enabled | Enforce SSL on connection to the PostgreSQL database | bool | true | |
| availability_type | The availability type for the master instance. | string | "ZONAL" | This is only used to set up high availability for the PostgreSQL instance. Can be either `ZONAL` or `REGIONAL`. |
| database_flags | Database flags for the master instance. | list(object({})) | | More details can be found [here](https://cloud.google.com/sql/docs/postgres/flags) |
| availability_type | The availability type for the primary instance. | string | "ZONAL" | This is only used to set up high availability for the PostgreSQL instance. Can be either `ZONAL` or `REGIONAL`. |
| database_flags | Database flags for the primary instance. | list(object({})) | | More details can be found [here](https://cloud.google.com/sql/docs/postgres/flags) |

Multiple SAS offerings require a second PostgreSQL instance referred to as SAS Common Data Store, or CDS PostgreSQL. For more information, see [Common Customizations](https://documentation.sas.com/?cdcId=itopscdc&cdcVersion=default&docsetId=dplyml0phy0dkr&docsetTarget=n08u2yg8tdkb4jn18u8zsi6yfv3d.htm#p0wkxxi9s38zbzn19ukjjaxsc0kl). A list of SAS offerings that require CDS PostgreSQL is provided in [SAS Common Data Store Requirements](https://documentation.sas.com/?cdcId=itopscdc&cdcVersion=default&docsetId=itopssr&docsetTarget=p05lfgkwib3zxbn1t6nyihexp12n.htm#n03wzanutmc6gon1val5fykas9aa). To create and configure an external CDS PostgreSQL instance in addition to the external platform PostgreSQL instance named `default`, specify `cds-postgres` as a second PostgreSQL instance, as shown in the example below.

Expand Down Expand Up @@ -306,4 +323,4 @@ postgres_servers = {
| gke_monitoring_enabled_components | List of services to monitor: SYSTEM_COMPONENTS, WORKLOADS (WORKLOADS deprecated in 1.24). | list of strings | ["SYSTEM_COMPONENTS"] | |
| enable_managed_prometheus | Enable Google Cloud [Managed Service for Prometheus](https://cloud.google.com/stackdriver/docs/managed-prometheus) for your cluster | boolean | false | |

Note: For additional details about Google Kubernetes Engine (GKE) integration with Cloud Logging and Cloud Monitoring, including Google Cloud [Managed Service for Prometheus](https://cloud.google.com/stackdriver/docs/managed-prometheus), view the ["Overview of Google Cloud's operations suite for GKE" documentation](https://cloud.google.com/stackdriver/docs/solutions/gke)
Note: For additional details about Google Kubernetes Engine (GKE) integration with Cloud Logging and Cloud Monitoring, including Google Cloud [Managed Service for Prometheus](https://cloud.google.com/stackdriver/docs/managed-prometheus), view the ["Overview of Google Cloud's operations suite for GKE" documentation](https://cloud.google.com/stackdriver/docs/solutions/gke)
6 changes: 5 additions & 1 deletion docs/user/TerraformGCPAuthentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ The Service Account will need the following [IAM roles](https://cloud.google.com
| `roles/container.admin` | Kubernetes Engine Admin | Cluster creation |
| `roles/container.clusterAdmin` | Kubernetes Engine Cluster Admin | Terraform Kubernetes Engine Module |
| `roles/container.developer` | Kubernetes Engine Developer | Cluster creation |
| `roles/file.editor` | Cloud Filestore Editor | Needed for [`storage_type=="HA"`](../CONFIG-VARS.md#storage) |
| `roles/file.editor` | Cloud Filestore Editor | Needed for [`storage_type=="ha" && storage_type_backend = "filestore"`](../CONFIG-VARS.md#storage) |
| `roles/netapp.admin` | NetApp Admin | Needed for [`storage_type=="ha" && storage_type_backend = "netapp"`](../CONFIG-VARS.md#storage) |
| `roles/netapp.viewer` | NetApp Viewer | Needed for [`storage_type=="ha" && storage_type_backend = "netapp"`](../CONFIG-VARS.md#storage) |
| `roles/iam.serviceAccountAdmin` | Service Account Admin | Terraform Kubernetes Engine Module |
| `roles/iam.serviceAccountUser` | Service Account User | Terraform Kubernetes Engine Module |
| `roles/resourcemanager.projectIamAdmin` | Project IAM Admin | Terraform Kubernetes Engine Module |
Expand All @@ -59,6 +61,8 @@ gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAM
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/container.clusterAdmin
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/container.developer
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/file.editor
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/netapp.admin
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/netapp.viewer
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/iam.serviceAccountAdmin
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/iam.serviceAccountUser
gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:${SA_NAME}@${PROJECT}.iam.gserviceaccount.com --role roles/resourcemanager.projectIamAdmin
Expand Down
2 changes: 1 addition & 1 deletion examples/sample-input-byo.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ postgres_servers = {
}

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 2
default_nodepool_vm_type = "n2-highmem-8"

Expand Down
2 changes: 1 addition & 1 deletion examples/sample-input-connect.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ postgres_servers = {
}

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 2
default_nodepool_vm_type = "n2-highmem-8"

Expand Down
5 changes: 3 additions & 2 deletions examples/sample-input-ha.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ postgres_servers = {
}

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 2
default_nodepool_vm_type = "n2-highmem-8"

Expand Down Expand Up @@ -94,5 +94,6 @@ jump_vm_admin = "jumpuser"
# Storage for Viya Compute Services
# Supported storage_type values
# "standard" - Custom managed NFS Server VM and disks
# "ha" - Google Filestore
# "ha" - Google Filestore or Google NetApp Volumes
storage_type = "ha"
storage_type_backend = "filestore" # "filestore" is the default, use "netapp" to create Google NetApp Volumes
2 changes: 1 addition & 1 deletion examples/sample-input-minimal.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ tags = {} # e.g., { "key1" = "value1", "key2" = "value2" }
# }

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 1
default_nodepool_vm_type = "n2-highmem-8"

Expand Down
2 changes: 1 addition & 1 deletion examples/sample-input.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ postgres_servers = {
}

# GKE config
kubernetes_version = "1.29"
kubernetes_version = "1.30"
default_nodepool_min_nodes = 2
default_nodepool_vm_type = "n2-highmem-8"

Expand Down
2 changes: 1 addition & 1 deletion linting-configs/.tflint.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

config {
# Enables module inspection.
module = true
call_module_type = "all"
}

plugin "google" {
Expand Down
6 changes: 6 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ locals {
: null
)

# Storage
storage_type_backend = (var.storage_type == "none" ? "none"
: var.storage_type == "standard" ? "nfs"
: var.storage_type == "ha" && var.storage_type_backend == "netapp" ? "netapp"
: var.storage_type == "ha" ? "filestore" : "none")

# Kubernetes
kubeconfig_path = var.iac_tooling == "docker" ? "/workspace/${var.prefix}-gke-kubeconfig.conf" : "${var.prefix}-gke-kubeconfig.conf"

Expand Down
24 changes: 20 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ EOT

resource "google_filestore_instance" "rwx" {
name = "${var.prefix}-rwx-filestore"
count = var.storage_type == "ha" ? 1 : 0
count = var.storage_type == "ha" && local.storage_type_backend == "filestore" ? 1 : 0
tier = upper(var.filestore_tier)
location = local.zone
labels = var.tags
Expand All @@ -91,7 +91,7 @@ data "google_container_engine_versions" "gke-version" {

module "gke" {
source = "terraform-google-modules/kubernetes-engine/google//modules/private-cluster"
version = "~> 31.0.0"
version = "~> 33.1.0"
project_id = var.project
name = "${var.prefix}-gke"
region = local.region
Expand Down Expand Up @@ -241,7 +241,7 @@ resource "local_file" "kubeconfig" {
# Module Registry - https://registry.terraform.io/modules/GoogleCloudPlatform/sql-db/google/12.0.0/submodules/postgresql
module "postgresql" {
source = "GoogleCloudPlatform/sql-db/google//modules/postgresql"
version = "~> 20.1.0"
version = "~> 22.1.0"
project_id = var.project

for_each = local.postgres_servers != null ? length(local.postgres_servers) != 0 ? local.postgres_servers : {} : {}
Expand Down Expand Up @@ -293,11 +293,27 @@ module "postgresql" {

module "sql_proxy_sa" {
source = "terraform-google-modules/service-accounts/google"
version = "~> 4.2.2"
version = "~> 4.4.0"
count = var.postgres_servers != null ? length(var.postgres_servers) != 0 ? 1 : 0 : 0
project_id = var.project
prefix = var.prefix
names = ["sql-proxy-sa"]
project_roles = ["${var.project}=>roles/cloudsql.admin"]
display_name = "IAC-managed service account for cluster ${var.prefix} and sql-proxy integration."
}

module "google_netapp" {
source = "./modules/google_netapp"

count = var.storage_type == "ha" && local.storage_type_backend == "netapp" ? 1 : 0

prefix = var.prefix
region = local.region
network = module.vpc.network_name
netapp_subnet_cidr = var.netapp_subnet_cidr
service_level = var.netapp_service_level
capacity_gib = var.netapp_capacity_gib
protocols = var.netapp_protocols
volume_path = "${var.prefix}-${var.netapp_volume_path}"
allowed_clients = join(",", [local.gke_subnet_cidr, local.misc_subnet_cidr])
}
Loading
Loading