From 8c90f44a78f09fd4753b84514b9de651ac6a3f93 Mon Sep 17 00:00:00 2001 From: rich-ehrhardt Date: Thu, 20 Oct 2022 09:02:41 +1100 Subject: [PATCH 01/13] Updates to latest Azure specific image Signed-off-by: rich-ehrhardt --- .github/workflows/verify-workflow.yaml | 2 +- launch.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify-workflow.yaml b/.github/workflows/verify-workflow.yaml index e957861..763beed 100644 --- a/.github/workflows/verify-workflow.yaml +++ b/.github/workflows/verify-workflow.yaml @@ -32,7 +32,7 @@ jobs: verify: runs-on: ubuntu-latest container: - image: quay.io/cloudnativetoolkit/cli-tools:v1.2-v2.1.3 + image: quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.4.20 options: --privileged --user root strategy: diff --git a/launch.sh b/launch.sh index aa3679e..448a398 100755 --- a/launch.sh +++ b/launch.sh @@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd $(dirname $0); pwd -P)" SRC_DIR="${SCRIPT_DIR}" -DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools:v1.2-v2.1.3" +DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.4.20" SUFFIX=$(echo $(basename ${SCRIPT_DIR}) | base64 | sed -E "s/[^a-zA-Z0-9_.-]//g" | sed -E "s/.*(.{5})/\1/g") CONTAINER_NAME="cli-tools-${SUFFIX}" From a2bf36fd983981978c361ee4ac15cc06b83f0aa8 Mon Sep 17 00:00:00 2001 From: rich-ehrhardt Date: Thu, 20 Oct 2022 15:24:50 +1100 Subject: [PATCH 02/13] Adds standard architecture Signed-off-by: rich-ehrhardt --- 2-standard/1-aro/.mocks/mock/main.tf | 0 2-standard/1-aro/.mocks/mock/terragrunt.hcl | 3 + .../101-azure-vnet-std.auto.tfvars | 18 ++ 2-standard/1-aro/101-azure-vnet-std/apply.sh | 118 +++++++ 2-standard/1-aro/101-azure-vnet-std/bom.yaml | 129 ++++++++ .../1-aro/101-azure-vnet-std/dependencies.dot | 26 ++ .../1-aro/101-azure-vnet-std/destroy.sh | 7 + .../101-azure-vnet-std/docs/azure-nsg.md | 68 ++++ .../docs/azure-resource-group.md | 55 ++++ .../101-azure-vnet-std/docs/azure-ssh-key.md | 75 +++++ .../docs/azure-vnet-subnets.md | 118 +++++++ .../101-azure-vnet-std/docs/azure-vnet.md | 59 ++++ .../docs/azure-vpn-server.md | 193 +++++++++++ 2-standard/1-aro/101-azure-vnet-std/main.tf | 114 +++++++ 2-standard/1-aro/101-azure-vnet-std/output.tf | 233 ++++++++++++++ .../1-aro/101-azure-vnet-std/providers.tf | 9 + .../1-aro/101-azure-vnet-std/terragrunt.hcl | 3 + .../1-aro/101-azure-vnet-std/variables.tf | 304 ++++++++++++++++++ .../1-aro/101-azure-vnet-std/version.tf | 8 + .../105-azure-aro-std.auto.tfvars | 21 ++ 2-standard/1-aro/105-azure-aro-std/apply.sh | 118 +++++++ 2-standard/1-aro/105-azure-aro-std/bom.yaml | 75 +++++ .../1-aro/105-azure-aro-std/dependencies.dot | 17 + 2-standard/1-aro/105-azure-aro-std/destroy.sh | 7 + .../1-aro/105-azure-aro-std/docs/azure-aro.md | 180 +++++++++++ .../docs/azure-resource-group.md | 55 ++++ .../docs/azure-vnet-subnets.md | 118 +++++++ .../105-azure-aro-std/docs/azure-vnet.md | 59 ++++ 2-standard/1-aro/105-azure-aro-std/main.tf | 48 +++ 2-standard/1-aro/105-azure-aro-std/output.tf | 51 +++ .../1-aro/105-azure-aro-std/providers.tf | 9 + .../1-aro/105-azure-aro-std/terragrunt.hcl | 32 ++ .../1-aro/105-azure-aro-std/variables.tf | 223 +++++++++++++ 2-standard/1-aro/105-azure-aro-std/version.tf | 8 + .../200-openshift-gitops.auto.tfvars | 27 ++ .../1-aro/200-openshift-gitops/apply.sh | 74 +++++ .../1-aro/200-openshift-gitops/bom.yaml | 102 ++++++ .../200-openshift-gitops/dependencies.dot | 30 ++ .../1-aro/200-openshift-gitops/destroy.sh | 7 + .../docs/argocd-bootstrap.md | 55 ++++ .../1-aro/200-openshift-gitops/docs/gitea.md | 32 ++ .../docs/gitops-cluster-config.md | 39 +++ .../docs/gitops-console-link-job.md | 41 +++ .../docs/gitops-namespace.md | 41 +++ .../200-openshift-gitops/docs/gitops-repo.md | 56 ++++ .../200-openshift-gitops/docs/namespace.md | 39 +++ .../200-openshift-gitops/docs/ocp-login.md | 36 +++ .../1-aro/200-openshift-gitops/docs/olm.md | 29 ++ .../docs/sealed-secret-cert.md | 38 +++ .../200-openshift-gitops/docs/util-clis.md | 45 +++ 2-standard/1-aro/200-openshift-gitops/main.tf | 129 ++++++++ .../1-aro/200-openshift-gitops/outputs.tf | 19 ++ .../1-aro/200-openshift-gitops/providers.tf | 6 + .../1-aro/200-openshift-gitops/terragrunt.hcl | 41 +++ .../1-aro/200-openshift-gitops/variables.tf | 231 +++++++++++++ .../1-aro/200-openshift-gitops/version.tf | 8 + .../1-aro/210-azure-default-storage/bom.yaml | 0 .../1-aro/210-azure-default-storage/main.tf | 3 + .../210-azure-default-storage/terragrunt.hcl | 15 + .../210-azure-portworx-storage.auto.tfvars | 27 ++ .../1-aro/210-azure-portworx-storage/apply.sh | 74 +++++ .../1-aro/210-azure-portworx-storage/bom.yaml | 83 +++++ .../dependencies.dot | 6 + .../210-azure-portworx-storage/destroy.sh | 7 + .../docs/azure-portworx.md | 120 +++++++ .../docs/ocp-login.md | 36 +++ .../1-aro/210-azure-portworx-storage/main.tf | 32 ++ .../210-azure-portworx-storage/providers.tf | 5 + .../210-azure-portworx-storage/terragrunt.hcl | 32 ++ .../210-azure-portworx-storage/variables.tf | 109 +++++++ .../210-azure-portworx-storage/version.tf | 8 + .../220-dev-tools/220-dev-tools.auto.tfvars | 18 ++ 2-standard/1-aro/220-dev-tools/apply.sh | 74 +++++ 2-standard/1-aro/220-dev-tools/bom.yaml | 80 +++++ .../1-aro/220-dev-tools/dependencies.dot | 29 ++ 2-standard/1-aro/220-dev-tools/destroy.sh | 7 + .../220-dev-tools/docs/gitops-artifactory.md | 39 +++ .../docs/gitops-buildah-unprivileged.md | 36 +++ .../220-dev-tools/docs/gitops-dashboard.md | 42 +++ .../220-dev-tools/docs/gitops-namespace.md | 41 +++ .../220-dev-tools/docs/gitops-pact-broker.md | 37 +++ .../1-aro/220-dev-tools/docs/gitops-repo.md | 56 ++++ .../220-dev-tools/docs/gitops-sonarqube.md | 42 +++ .../docs/gitops-swagger-editor.md | 196 +++++++++++ .../docs/gitops-tekton-resources.md | 35 ++ .../1-aro/220-dev-tools/docs/util-clis.md | 45 +++ 2-standard/1-aro/220-dev-tools/main.tf | 124 +++++++ 2-standard/1-aro/220-dev-tools/providers.tf | 6 + 2-standard/1-aro/220-dev-tools/terragrunt.hcl | 43 +++ 2-standard/1-aro/220-dev-tools/variables.tf | 249 ++++++++++++++ 2-standard/1-aro/220-dev-tools/version.tf | 8 + 2-standard/1-aro/README.md | 187 +++++++++++ 2-standard/1-aro/launch.sh | 102 ++++++ 2-standard/1-aro/layers.yaml | 10 + 2-standard/1-aro/terragrunt.hcl | 36 +++ check-vpn.sh | 58 ++++ launch.sh | 11 +- setup-workspace.sh | 6 +- terraform.tfvars.template-standard-aro | 32 ++ 99 files changed, 5884 insertions(+), 8 deletions(-) create mode 100644 2-standard/1-aro/.mocks/mock/main.tf create mode 100644 2-standard/1-aro/.mocks/mock/terragrunt.hcl create mode 100644 2-standard/1-aro/101-azure-vnet-std/101-azure-vnet-std.auto.tfvars create mode 100755 2-standard/1-aro/101-azure-vnet-std/apply.sh create mode 100644 2-standard/1-aro/101-azure-vnet-std/bom.yaml create mode 100644 2-standard/1-aro/101-azure-vnet-std/dependencies.dot create mode 100755 2-standard/1-aro/101-azure-vnet-std/destroy.sh create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-nsg.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-resource-group.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-ssh-key.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet-subnets.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/docs/azure-vpn-server.md create mode 100644 2-standard/1-aro/101-azure-vnet-std/main.tf create mode 100644 2-standard/1-aro/101-azure-vnet-std/output.tf create mode 100644 2-standard/1-aro/101-azure-vnet-std/providers.tf create mode 100644 2-standard/1-aro/101-azure-vnet-std/terragrunt.hcl create mode 100644 2-standard/1-aro/101-azure-vnet-std/variables.tf create mode 100644 2-standard/1-aro/101-azure-vnet-std/version.tf create mode 100644 2-standard/1-aro/105-azure-aro-std/105-azure-aro-std.auto.tfvars create mode 100755 2-standard/1-aro/105-azure-aro-std/apply.sh create mode 100644 2-standard/1-aro/105-azure-aro-std/bom.yaml create mode 100644 2-standard/1-aro/105-azure-aro-std/dependencies.dot create mode 100755 2-standard/1-aro/105-azure-aro-std/destroy.sh create mode 100644 2-standard/1-aro/105-azure-aro-std/docs/azure-aro.md create mode 100644 2-standard/1-aro/105-azure-aro-std/docs/azure-resource-group.md create mode 100644 2-standard/1-aro/105-azure-aro-std/docs/azure-vnet-subnets.md create mode 100644 2-standard/1-aro/105-azure-aro-std/docs/azure-vnet.md create mode 100644 2-standard/1-aro/105-azure-aro-std/main.tf create mode 100644 2-standard/1-aro/105-azure-aro-std/output.tf create mode 100644 2-standard/1-aro/105-azure-aro-std/providers.tf create mode 100644 2-standard/1-aro/105-azure-aro-std/terragrunt.hcl create mode 100644 2-standard/1-aro/105-azure-aro-std/variables.tf create mode 100644 2-standard/1-aro/105-azure-aro-std/version.tf create mode 100644 2-standard/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars create mode 100755 2-standard/1-aro/200-openshift-gitops/apply.sh create mode 100644 2-standard/1-aro/200-openshift-gitops/bom.yaml create mode 100644 2-standard/1-aro/200-openshift-gitops/dependencies.dot create mode 100755 2-standard/1-aro/200-openshift-gitops/destroy.sh create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/argocd-bootstrap.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/gitea.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/gitops-console-link-job.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/gitops-namespace.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/gitops-repo.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/namespace.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/ocp-login.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/olm.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/sealed-secret-cert.md create mode 100644 2-standard/1-aro/200-openshift-gitops/docs/util-clis.md create mode 100644 2-standard/1-aro/200-openshift-gitops/main.tf create mode 100644 2-standard/1-aro/200-openshift-gitops/outputs.tf create mode 100644 2-standard/1-aro/200-openshift-gitops/providers.tf create mode 100644 2-standard/1-aro/200-openshift-gitops/terragrunt.hcl create mode 100644 2-standard/1-aro/200-openshift-gitops/variables.tf create mode 100644 2-standard/1-aro/200-openshift-gitops/version.tf create mode 100644 2-standard/1-aro/210-azure-default-storage/bom.yaml create mode 100644 2-standard/1-aro/210-azure-default-storage/main.tf create mode 100644 2-standard/1-aro/210-azure-default-storage/terragrunt.hcl create mode 100644 2-standard/1-aro/210-azure-portworx-storage/210-azure-portworx-storage.auto.tfvars create mode 100755 2-standard/1-aro/210-azure-portworx-storage/apply.sh create mode 100644 2-standard/1-aro/210-azure-portworx-storage/bom.yaml create mode 100644 2-standard/1-aro/210-azure-portworx-storage/dependencies.dot create mode 100755 2-standard/1-aro/210-azure-portworx-storage/destroy.sh create mode 100644 2-standard/1-aro/210-azure-portworx-storage/docs/azure-portworx.md create mode 100644 2-standard/1-aro/210-azure-portworx-storage/docs/ocp-login.md create mode 100644 2-standard/1-aro/210-azure-portworx-storage/main.tf create mode 100644 2-standard/1-aro/210-azure-portworx-storage/providers.tf create mode 100644 2-standard/1-aro/210-azure-portworx-storage/terragrunt.hcl create mode 100644 2-standard/1-aro/210-azure-portworx-storage/variables.tf create mode 100644 2-standard/1-aro/210-azure-portworx-storage/version.tf create mode 100644 2-standard/1-aro/220-dev-tools/220-dev-tools.auto.tfvars create mode 100755 2-standard/1-aro/220-dev-tools/apply.sh create mode 100644 2-standard/1-aro/220-dev-tools/bom.yaml create mode 100644 2-standard/1-aro/220-dev-tools/dependencies.dot create mode 100755 2-standard/1-aro/220-dev-tools/destroy.sh create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-artifactory.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-buildah-unprivileged.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-dashboard.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-namespace.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-pact-broker.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-repo.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-sonarqube.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-swagger-editor.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/gitops-tekton-resources.md create mode 100644 2-standard/1-aro/220-dev-tools/docs/util-clis.md create mode 100644 2-standard/1-aro/220-dev-tools/main.tf create mode 100644 2-standard/1-aro/220-dev-tools/providers.tf create mode 100644 2-standard/1-aro/220-dev-tools/terragrunt.hcl create mode 100644 2-standard/1-aro/220-dev-tools/variables.tf create mode 100644 2-standard/1-aro/220-dev-tools/version.tf create mode 100644 2-standard/1-aro/README.md create mode 100755 2-standard/1-aro/launch.sh create mode 100644 2-standard/1-aro/layers.yaml create mode 100644 2-standard/1-aro/terragrunt.hcl create mode 100755 check-vpn.sh create mode 100644 terraform.tfvars.template-standard-aro diff --git a/2-standard/1-aro/.mocks/mock/main.tf b/2-standard/1-aro/.mocks/mock/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/2-standard/1-aro/.mocks/mock/terragrunt.hcl b/2-standard/1-aro/.mocks/mock/terragrunt.hcl new file mode 100644 index 0000000..e147285 --- /dev/null +++ b/2-standard/1-aro/.mocks/mock/terragrunt.hcl @@ -0,0 +1,3 @@ +include "root" { + path = find_in_parent_folders() +} diff --git a/2-standard/1-aro/101-azure-vnet-std/101-azure-vnet-std.auto.tfvars b/2-standard/1-aro/101-azure-vnet-std/101-azure-vnet-std.auto.tfvars new file mode 100644 index 0000000..e3834cb --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/101-azure-vnet-std.auto.tfvars @@ -0,0 +1,18 @@ +## resource_group_name: The name of the resource group +#resource_group_name="" + +## region: The Azure location where the resource group will be provisioned +#region="" + +## subscription_id: the value of subscription_id +#subscription_id="" + +## client_id: the value of client_id +#client_id="" + +## client_secret: the value of client_secret +#client_secret="" + +## tenant_id: the value of tenant_id +#tenant_id="" + diff --git a/2-standard/1-aro/101-azure-vnet-std/apply.sh b/2-standard/1-aro/101-azure-vnet-std/apply.sh new file mode 100755 index 0000000..cc88204 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/apply.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +VARIABLES_FILE="${1}" +if [[ -z "${VARIABLES_FILE}" ]]; then + VARIABLES_FILE="variables.yaml" +fi + +YQ=$(command -v yq4 || command -v yq) +if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g") == "3" ]]; then + echo "yq v4 is required" + exit 1 +fi + +if ! command -v jq 1> /dev/null 2> /dev/null; then + echo "jq is required" + exit 1 +fi + +CREDENTIALS_PROPERTIES="credentials.properties" +TERRAFORM_TFVARS="terraform/terraform.tfvars" + +if [[ -f "${TERRAFORM_TFVARS}" ]]; then + cp "${TERRAFORM_TFVARS}" "${TERRAFORM_TFVARS}.backup" + rm "${TERRAFORM_TFVARS}" +fi + +if [[ -f "${CREDENTIALS_PROPERTIES}" ]]; then + cp "${CREDENTIALS_PROPERTIES}" "${CREDENTIALS_PROPERTIES}.backup" + rm "${CREDENTIALS_PROPERTIES}" +fi +touch "${CREDENTIALS_PROPERTIES}" + +if [[ ! -f "${VARIABLES_FILE}" ]]; then + echo "Variables can be provided in a yaml file passed as the first argument" + echo "" +fi + +TMP_VARIABLES_FILE="${VARIABLES_FILE}.tmp" + +echo "variables: []" > ${TMP_VARIABLES_FILE} + +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" + + local variable_name="TF_VAR_${name}" + + environment_variable=$(env | grep "${variable_name}" | sed -E 's/.*=(.*).*/\1/g') + value="${environment_variable}" + if [[ -f "${VARIABLES_FILE}" ]]; then + value=$(cat "${VARIABLES_FILE}" | NAME="${name}" ${YQ} e -o json '.variables[] | select(.name == env(NAME)) | .value // ""' - | jq -c -r '.') + if [[ -z "${value}" ]]; then + value="${environment_variable}" + fi + fi + + while [[ -z "${value}" ]]; do + echo "Provide a value for '${name}':" + if [[ -n "${description}" ]]; then + echo " ${description}" + fi + sensitive_flag="" + if [[ "${sensitive}" == "true" ]]; then + sensitive_flag="-s" + fi + default_prompt="" + if [[ -n "${default_value}" ]]; then + default_prompt="(${default_value}) " + fi + read -u 1 ${sensitive_flag} -p "> ${default_prompt}" value + value=${value:-$default_value} + done + + output_value=$(echo "${value}" | sed 's/"/\\"/g') + + if [[ "${sensitive}" != "true" ]]; then + echo "${name} = \"${output_value}\"" >> "${TERRAFORM_TFVARS}" + NAME="${name}" VALUE="${value}" ${YQ} e -i -P '.variables += [{"name": env(NAME), "value": env(VALUE)}]' "${TMP_VARIABLES_FILE}" + else + echo "export ${name}=\"${output_value}\"" >> "${CREDENTIALS_PROPERTIES}" + fi +} + +cat "bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while read name; do + variable=$(cat "bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME))' -) + + default_value=$(echo "${variable}" | ${YQ} e -o json '.defaultValue // ""' - | jq -c -r '.') + sensitive=$(echo "${variable}" | ${YQ} e '.sensitive // false' -) + description=$(echo "${variable}" | ${YQ} e '.description // ""' -) + + process_variable "${name}" "${default_value}" "${sensitive}" "${description}" +done + +cat "${VARIABLES_FILE}" | ${YQ} e '.variables[]' -o json - | jq -c '.' | while read var; do + name=$(echo "${var}" | jq -r '.name') + + value=$(echo "${var}" | jq -r '.value // empty') + sensitive=$(echo "${var}" | jq -r '.sensitive') + + bom_var=$(cat bom.yaml | ${YQ} e '.spec.variables[]' -o json - | jq --arg NAME "${name}" -c 'select(.name == $NAME)') + + if [[ -z "${bom_var}" ]]; then + process_variable "${name}" "${value}" "${sensitive}" "" + fi +done + +cp "${TMP_VARIABLES_FILE}" "${VARIABLES_FILE}" +rm "${TMP_VARIABLES_FILE}" + +source credentials.properties + +cd terraform +terraform init +terraform apply diff --git a/2-standard/1-aro/101-azure-vnet-std/bom.yaml b/2-standard/1-aro/101-azure-vnet-std/bom.yaml new file mode 100644 index 0000000..15d2274 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/bom.yaml @@ -0,0 +1,129 @@ +apiVersion: cloud.ibm.com/v1alpha1 +kind: BillOfMaterial +metadata: + name: 101-azure-vnet-std + labels: + type: infrastructure + platform: azure + code: '101' + annotations: + displayName: Azure VNet + description: Azure base infrastructure for OpenShift standard architecture + vpn/required: false +spec: + modules: + - name: azure-resource-group + alias: resource_group + version: v1.1.1 + - name: azure-vnet + alias: vnet + version: v1.1.3 + variables: + - name: address_prefixes + value: + - 10.0.0.0/20 + - name: azure-vnet-subnets + alias: master_subnet + version: v1.3.9 + default: true + variables: + - name: label + value: master + - name: ipv4_cidr_blocks + value: + - 10.0.1.0/24 + - name: service_endpoints + value: + - Microsoft.ContainerRegistry + - Microsoft.Storage + - name: disable_private_link_endpoint_network_policies + value: true + - name: disable_private_link_service_network_policies + value: true + - name: azure-vnet-subnets + alias: worker_subnet + version: v1.3.9 + variables: + - name: label + value: worker + - name: ipv4_cidr_blocks + value: + - 10.0.2.0/24 + - name: service_endpoints + value: + - Microsoft.ContainerRegistry + - Microsoft.Storage + - name: azure-vnet-subnets + alias: ingress_subnet + version: v1.3.9 + variables: + - name: label + value: ingress + - name: ipv4_cidr_blocks + value: + - 10.0.3.0/24 + - name: azure-nsg + alias: nsg + version: v1.0.5 + variables: + - name: acl_rules + value: + - name: ssh-inbound + priority: '101' + access: Allow + protocol: Tcp + direction: Inbound + source_addr: '*' + destination_addr: '*' + source_ports: '*' + destination_ports: '22' + - name: vpn-inbound-tcp + priority: '102' + access: Allow + protocol: Tcp + direction: Inbound + source_addr: '*' + destination_addr: '*' + source_ports: '*' + destination_ports: '443' + - name: vpn-inbound-udp + priority: '103' + access: Allow + protocol: Udp + direction: Inbound + source_addr: '*' + destination_addr: '*' + source_ports: '*' + destination_ports: '1194' + dependencies: + - name: subnets + ref: ingress_subnet + - name: azure-ssh-key + alias: ssh-keys + version: v1.0.6 + - name: azure-vpn-server + alias: vpn-server + version: v1.0.1 + variables: + - name: private_network_cidrs + value: + - 10.0.0.0/20 + dependencies: + - name: subnet + ref: ingress_subnet + variables: + - name: resource_group_name + type: string + description: The name of the resource group + - name: region + type: string + description: The Azure location where the resource group will be provisioned + - name: subscription_id + type: string + - name: client_id + type: string + - name: client_secret + type: string + sensitive: true + - name: tenant_id + type: string diff --git a/2-standard/1-aro/101-azure-vnet-std/dependencies.dot b/2-standard/1-aro/101-azure-vnet-std/dependencies.dot new file mode 100644 index 0000000..ee52254 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/dependencies.dot @@ -0,0 +1,26 @@ +digraph { + rankdir="BT" + "resource_group (azure-resource-group)" +"vnet (azure-vnet)" -> "resource_group (azure-resource-group)" +"vnet (azure-vnet)" +"master_subnet (azure-vnet-subnets)" -> "resource_group (azure-resource-group)" +"master_subnet (azure-vnet-subnets)" -> "vnet (azure-vnet)" +"master_subnet (azure-vnet-subnets)" +"worker_subnet (azure-vnet-subnets)" -> "resource_group (azure-resource-group)" +"worker_subnet (azure-vnet-subnets)" -> "vnet (azure-vnet)" +"worker_subnet (azure-vnet-subnets)" +"ingress_subnet (azure-vnet-subnets)" -> "resource_group (azure-resource-group)" +"ingress_subnet (azure-vnet-subnets)" -> "vnet (azure-vnet)" +"ingress_subnet (azure-vnet-subnets)" +"nsg (azure-nsg)" -> "resource_group (azure-resource-group)" +"nsg (azure-nsg)" -> "vnet (azure-vnet)" +"nsg (azure-nsg)" -> "ingress_subnet (azure-vnet-subnets)" +"nsg (azure-nsg)" +"ssh-keys (azure-ssh-key)" -> "resource_group (azure-resource-group)" +"ssh-keys (azure-ssh-key)" +"vpn-server (azure-vpn-server)" -> "resource_group (azure-resource-group)" +"vpn-server (azure-vpn-server)" -> "vnet (azure-vnet)" +"vpn-server (azure-vpn-server)" -> "master_subnet (azure-vnet-subnets)" +"vpn-server (azure-vpn-server)" -> "ssh-keys (azure-ssh-key)" +"vpn-server (azure-vpn-server)" + } \ No newline at end of file diff --git a/2-standard/1-aro/101-azure-vnet-std/destroy.sh b/2-standard/1-aro/101-azure-vnet-std/destroy.sh new file mode 100755 index 0000000..7c27549 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/destroy.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd "${SCRIPT_DIR}/terraform" +terraform init +terraform destroy -auto-approve diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-nsg.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-nsg.md new file mode 100644 index 0000000..111346b --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-nsg.md @@ -0,0 +1,68 @@ +# Azure Network Security Group + +## Module Overview + +Module creates a network security group (NSG) on Azure with provided rules and associates with provided subnets. It includes the following resources: +- azurerm_network_security_group +- azurerm_subnet_network_security_group_association + +### Software dependencies + +This module has no dependencies on software components. + +### Command line tools + +- terraform >= 1.2.6 + +### Module dependencies + +- cloud-native-toolkit/terraform-azure-resource-group +- cloud-native-toolkit/terraform-azure-vnet +- cloud-native-toolkit/terraform-azure-subnets (optional if associating NSG with one or more subnets) + +## Example Usage + +```hcl-terraform +module "nsg" { + source = "github.com/cloud-native-toolkit/terraform-azure-nsg" + + name_prefix = "example" + resource_group_name = module.resource_group.name + region = module.resource_group.region + virtual_network_name = module.vnet.name + subnets = [module.subnets.name[0], module.subnets.name[1]] + acl_rules = [{ + name = "ssh-inbound" + priority = "101" + access = "Allow" + protocol = "Tcp" + direction = "Inbound" + source_addr = "*" + destination_addr = "*" + source_ports = "*" + destination_ports = "22" + } + ] +} +``` + +## Input Variables + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| resource_group_name | Mandatory | "" | The resource group into which to deploy the NSG | +| region | Mandatory | "" | Region into which to deploy the NSG | +| virtual_network_name | Mandatory | "" | The VNet into which to deploy the NSG | +| name_prefix | Optional | "" | The prefix for the NSG name (module will append "-nsg" to this variable) | +| name | Optional | "" | The full name for the NSG. One of name or name_prefix must be specified. | +| subnet_ids | Optional | [] | List of subnet ids in the VNet to which to associate the NSG when created | +| acl_rules | Optional | [] | List of ACL rules to apply (refer to variables.tf for details) | + +## Output Variables + +This module has the following output variables: +| Variable | Description | +| -------------------------------- | ----------------------------------------------------------------------------- | +| id | The Azure identification string of the created NSG | +| name | The name of the created NSG | \ No newline at end of file diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-resource-group.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-resource-group.md new file mode 100644 index 0000000..de8ba3c --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-resource-group.md @@ -0,0 +1,55 @@ +# Azure Resource Group + +## Module overview + +### Description + +This module provisions a resource group in Azure. + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- Azure provider >= 2.91.0 + +### Module dependencies + +None + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 2.91.0" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group" + + resource_group_name = var.resource_group_name + region = var.region +} +``` + diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-ssh-key.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-ssh-key.md new file mode 100644 index 0000000..6b76f18 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-ssh-key.md @@ -0,0 +1,75 @@ +# Azure SSH Key + +## Module overview + +### Description + +This module stores a public key into the Azure vault. If a key is not passed to the module, a new key pair is created and stored in the current working directory. + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- Azure provider >= 2.91.0 + +### Module dependencies + +This module makes use of the output from other modules: + +- Azure resource group - github.com/cloud-native-toolkit/terraform-azure-resource-group >= 1.0.2 + +### Example usage + +```hcl-terraform +module "ssh_key" { + source = "github.com/cloud-native-toolkit/terraform-azure-ssh-key" + + key_name = "test-key" + resource_group_name = module.resource_group.name + region= module.resource_group.region + store_path = "${path.cwd}/${var.path_offset}" + +} +``` + +## Variables + +### Inputs + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| key_name | Optional | "" | Name to give to the SSH key | +| name_prefix | Optional | "" | Prefix for the SSH key. If neither key_name nor name_prefix are provided, a random name is assigned. | +| resource_group_name | Optional | "" | Name of the resource group if storing the SSH key in the Azure vault | +| region | Optional | "" | Azure location if storing the SSH key in the Azure vault. | +| store_path | Optional | CWD | Path offset from current working directory (CWD) to store keys. | +| public_file_permissions | Optional | 0600 | Permissions for created public key file | +| private_file_permissions | Optional | 0400 | Permissions for created private key file | +| store_key_in_vault | Optional | true | Flag to specify whether to store generated keys in Azure vault | +| ssh_key | Optional | "" | Path to existing public key to used | +| algorithm | Optional | RSA | Encryption algorithm to be used (RSA, ECDSA or ED25519) | +| rsa_bits | Optional | 4096 | Number of bits if using RSA encryption | +| ecdsa_curve | Optional | P224 | Curve to use if using ECDSA | +| tags | Optional | "" | Extra tags to be added to the Azure vault entry. | + +### Outputs + +The module outputs the following values: +| Output | Description | +| -------------------------------- | -------------------------------------------------------------------------- | +| id | The Id of the Azure vault entry if created | +| pub_key | The public key | +| pub_key_file | Filename of the public key | +| private_key | The private key (sensitive) | +| private_key_file | Filename of the private key | +| path | Path to the keys | +| name | Name of the created key set | \ No newline at end of file diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet-subnets.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet-subnets.md new file mode 100644 index 0000000..e648a22 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet-subnets.md @@ -0,0 +1,118 @@ +# Azure VNet Subnets + +## Module overview + +### Description + +Module that provisions virtual network subnets on Azure, including the following resources: +- subnet +- network security group +- security group subnet association + +The number of subnets created is controlled by the number of subnet CIDR's supplied and the provision flag. If the provison flag is set to false (it is true by default), the module will not provision anything and will only read the provided subnet name details (use the subnet_name variable to supply the subnet name). + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- Azure provider + +### Module dependencies + +This module makes use of the output from other modules: + +- Resource Group - github.com/cloud-native-toolkit/terraform-azure-resource-group +- VNet - github.com/cloud-native-toolkit/terraform-azure-vnet + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "subnets" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets" + + resource_group_name = module.resource_group.name + region = var.region + vpc_name = module.vpc.name + ipv4_cidr_blocks = ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"] + acl_rules = [{ + name = "ssh-inbound" + action = "Allow" + direction = "Inbound" + source = "*" + destination = "*" + tcp = { + destination_port_range = "22" + source_port_range = "*" + } + }, { + name = "internal-only" + action = "Allow" + direction = "Inbound" + source = "10.0.0.0/16" + destination = "10.0.0.0/24" + udp = { + destination_port_range = "1024 - 2048" + source_port_range = "*" + } + }] +} +``` + +## Input Variables + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| resource_group_name | Mandatory | | The resource group into which to deploy or query | +| region | Mandatory | | Region into which to deploy or query | +| vnet_name | Mandatory | | Name of the VNet into which to deploy or query | +| subnet_name | Optional | "" | Name of an existing subnet to query | +| label | Optional | "" | Label to use in subnet names | +| provision | Optional | true | Flag to provision new resources or query existing if false | +| ipv4_cidr_blocks | Optional | [] | List of CIDRs for subnets to be created | +| acl_rules | Optional | [] | List of rules to create and associate with the subent(s) | +| service_endpoints | Optional | Microsoft.ContainerRegistry | List of service endpoints for the subnet(s)| +| disable_private_link_endpoint_network_policies | Optional | false | Flag to disable private link endpoint network policies in the subnet(s) | +| disable_private_link_service_network_policies | Optional | false | Flag to disable private link service network policies in the subnet(s) | + +## Output Variables + +This module has the following output variables: +| Variable | Description | +| -------------------------------- | ----------------------------------------------------------------------------- | +| id | The Azure identification string of the created RTB | +| name | The name of the subnet if creating only one | +| count | The number of subnets created or queried | +| ids | List of the ids of the created subnets | +| id | Id of the first created subnet | +| names | List of the names of the created subnets | +| subnets | Object list for the created subnets | +| acl_id | Id of the created network security group | +| vnet_name | Name of the VNet where the subnets were provisioned (passthrough) | +| vnet_id | Id of the VNet where the subnets were provisoned | +| cidr_block | The list of CIDRs assigned to the subnets (passthrough) | diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet.md new file mode 100644 index 0000000..5eeda7e --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet.md @@ -0,0 +1,59 @@ +# Azure Virtual Network + +## Module overview + +### Description + +Module to provision a virtual network on Azure + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v1.2.7 + +#### Terraform providers + +- Azure provider >= 3.0.0 + +### Module dependencies + +This module makes use of the output from other modules: + +- Resource group - github.com/cloud-native-toolkit/terraform-azure-resource-group + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "=3.0.0" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "vpc" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet" + + resource_group_name = module.resource_group.name + region = var.region + name_prefix = var.name_prefix + address_prefix_count = 1 + address_prefixes = ["10.0.0.0/16"] +} +``` diff --git a/2-standard/1-aro/101-azure-vnet-std/docs/azure-vpn-server.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vpn-server.md new file mode 100644 index 0000000..3a86e3b --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vpn-server.md @@ -0,0 +1,193 @@ +# Azure VPN Server + +## Module overview + +Module creates an Azure VPN Server. It includes the following resources: +- read local public key file +- Azure VM creation via module with custom bootstrap script for VPN server +- creation and application of VPN server configuration +- creation and download of VPN client connection file + +### Software dependencies + +- terraform >= 1.2.6 + +### Terraform providers + +- Azure provider >= 3.0.0 + +### Module dependencies + +This modules makes use of the output from other modules: +- Azure Resource Group - github.com/cloud-native-toolkit/terraform-azure-resource-group +- Azure VNet - github.com/cloud-native-toolkit/terraform-azure-vnet +- Azure Subnets - github.com/cloud-native-toolkit/terraform-azure-subnets +- Azure SSH Key - github.com/cloud-native-toolkit/teraform-azure-ssh-key + +## Example Usage + +```hcl-terraform +locals { + name_prefix = "myexample" + region = "eastus" + vnet_cidr = "10.0.0.0/18" + subnet_cidrs = cidrsubnets(local.vnet_cidr, 2, 2) + ingress_cidr = local.subnet_cidrs[0] + internal_cidr = local.subnet_cidrs[1] +} + +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group?ref=v1.1.1" + + resource_group_name = "${local.name_prefix}-rg" + region = local.region +} + +module "vnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet?ref=v1.1.3" + + name_prefix = local.name_prefix + resource_group_name = module.resource_group.name + region = module.resource_group.region + address_prefixes = [local.vnet_cidr] +} + +module "ingress-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.7" + + label = "ingress" + resource_group_name = module.resource_group.name + region = module.resource_group.region + vnet_name = module.vnet.name + ipv4_cidr_blocks = [local.ingress_cidr] + acl_rules = [] +} + +module "internal-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.7" + + label = "internal" + resource_group_name = module.resource_group.name + region = module.resource_group.region + vnet_name = module.vnet.name + ipv4_cidr_blocks = [local.internal_cidr] + acl_rules = [] +} + +module "nsg" { + source = "github.com/cloud-native-toolkit/terraform-azure-nsg?ref=v1.0.5" + + + name_prefix = local.name_prefix + resource_group_name = module.resource_group.name + region = module.resource_group.region + virtual_network_name = module.vnet.name + subnet_ids = [module.ingress-subnet.id] + acl_rules = [{ + name = "ssh-inbound" // Required for VPN configuration + priority = "102" + access = "Allow" + protocol = "Tcp" + direction = "Inbound" + source_addr = "*" + destination_addr = "*" + source_ports = "*" + destination_ports = "22" + },{ + name = "vpn-inbound-tcp" + priority = "103" + access = "Allow" + protocol = "Tcp" + direction = "Inbound" + source_addr = "*" + destination_addr = "*" + source_ports = "*" + destination_ports = "443" + },{ + name = "vpn-inbound-udp" + priority = "104" + access = "Allow" + protocol = "Udp" + direction = "Inbound" + source_addr = "*" + destination_addr = "*" + source_ports = "*" + destination_ports = "1194" + } + ] +} + +module "route-table" { + source = "github.com/cloud-native-toolkit/terraform-azure-rtb?ref=v1.0.0" + + name_prefix = local.name_prefix + resource_group_name = module.resource_group.name + region = module.resource_group.region + subnet_ids = [module.ingress-subnet.id, module.internal-subnet.id] + + routes = [{ + name = "internal-route" + address_prefix = local.vnet_cidr + next_hop_type = "VnetLocal" + next_hop_in_ip_address = "" + }] +} + +module "ssh-keys" { + source = "github.com/cloud-native-toolkit/terraform-azure-ssh-key?ref=v1.0.6" + + key_name = "${local.name_prefix}-key" + resource_group_name = module.resource_group.name + region = module.resource_group.region + store_path = "${path.cwd}/.ssh" +} + +module "vpn-server" { + source = "github.com/cloud-native-toolkit/terraform-azure-vpn-server" + + name_prefix = "${local.name_prefix}-vpn" + resource_group_name = module.resource_group.name + virtual_network_name = module.vnet.name + subnet_id = module.ingress-subnet.id + pub_ssh_key_file = module.ssh-keys.pub_key_file + private_key_file = module.ssh-keys.private_key_file + private_network_cidrs = [local.vnet_cidr] +} +``` +## Variables + +### Inputs + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| resource_group_name | Mandatory | | The resource group to which to associate the VPN Server | +| virtual_network_name | Mandatory | | The virtual network to which to associate the VPN Server | +| subnet_id | Mandatory | | The id of the subnet to which to associate the VPN Server| +| pub_ssh_key_file | Mandatory | | Path to the public SSH key for VPN Server access. | +| private_key_file | Mandatory | | Path to the private SSH key for VPN Server access. | +| private_network_cidrs | Mandatory | | List of CIDRs in the private network reachable via the VPN server. | +| private_dns | Optional | ["168.63.129.16"] | List of private DNS servers. | +| name_prefix | Optional | open-vpn | Name to prefix resources created | +| client_network | Optional | 172.27.224.0 | Network address for VPN clients (default = \"172.27.224.0\") | +| client_network_bits | Optional | 24 | Number of netmask bits for the VPN client network (default = \"24\") | +| private_ip_address_allocation_type | Optional | Dynamic | The Azure subnet private ip address alocation type - Dynamic or Static (default = \"Dynamic\") | +| admin_username | Optional | azureuser | Username for the admin user (default = \"azureuser\") | +| bootstrap_script | Mandatory | | Path to file with the bootstrap script (default = \"./template/user-data.sh\") | +| vm_size | Optional | Standard_F2 | This is the size of Virtual Machine (defualt = \"Standard_F2\") | +| storage_type | Optional | Standard_LRS | Storage account type | +| vm_public_ip_sku | Optional | Standard | Public IP SKU Size (default = \"Standard\" | +| vm_public_ip_allocation_method | Optional | Static | The Azure subnet Public ip address alocation type - Dynamic or Static (default = \"Static\" | + +### Outputs + +The module outputs the following values: +| Output | Description | +| -------------------------------- | -------------------------------------------------------------------------- | +| id | The Id of the deployed vpn server | +| vm_public_ip | The address of the public IP if created | +| vm_public_fqdn | The FQDN of the public IP if created | +| vm_private_ip | The address of the VM on the supplied subnet | +| admin_username | The name of the administrator username | +| client_config_file | VPN server client configuration file to connect vpn server | + diff --git a/2-standard/1-aro/101-azure-vnet-std/main.tf b/2-standard/1-aro/101-azure-vnet-std/main.tf new file mode 100644 index 0000000..47a9ea4 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/main.tf @@ -0,0 +1,114 @@ +module "ingress_subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + + acl_rules = var.ingress_subnet_acl_rules == null ? null : jsondecode(var.ingress_subnet_acl_rules) + disable_private_link_endpoint_network_policies = var.ingress_subnet_disable_private_link_endpoint_network_policies + disable_private_link_service_network_policies = var.ingress_subnet_disable_private_link_service_network_policies + ipv4_cidr_blocks = var.ingress_subnet_ipv4_cidr_blocks == null ? null : jsondecode(var.ingress_subnet_ipv4_cidr_blocks) + label = var.ingress_subnet_label + provision = var.ingress_subnet_provision + region = var.region + resource_group_name = module.resource_group.name + service_endpoints = var.ingress_subnet_service_endpoints == null ? null : jsondecode(var.ingress_subnet_service_endpoints) + subnet_name = var.ingress_subnet_subnet_name + vnet_name = module.vnet.name +} +module "master_subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + + acl_rules = var.master_subnet_acl_rules == null ? null : jsondecode(var.master_subnet_acl_rules) + disable_private_link_endpoint_network_policies = var.master_subnet_disable_private_link_endpoint_network_policies + disable_private_link_service_network_policies = var.master_subnet_disable_private_link_service_network_policies + ipv4_cidr_blocks = var.master_subnet_ipv4_cidr_blocks == null ? null : jsondecode(var.master_subnet_ipv4_cidr_blocks) + label = var.master_subnet_label + provision = var.master_subnet_provision + region = var.region + resource_group_name = module.resource_group.name + service_endpoints = var.master_subnet_service_endpoints == null ? null : jsondecode(var.master_subnet_service_endpoints) + subnet_name = var.master_subnet_subnet_name + vnet_name = module.vnet.name +} +module "nsg" { + source = "github.com/cloud-native-toolkit/terraform-azure-nsg?ref=v1.0.5" + + acl_rules = var.nsg_acl_rules == null ? null : jsondecode(var.nsg_acl_rules) + name = var.nsg_name + name_prefix = var.name_prefix + region = var.region + resource_group_name = module.resource_group.name + subnet_ids = module.ingress_subnet.ids + virtual_network_name = module.vnet.name +} +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group?ref=v1.1.1" + + provision = var.resource_group_provision + region = var.region + resource_group_name = var.resource_group_name + sync = var.resource_group_sync +} +module "ssh-keys" { + source = "github.com/cloud-native-toolkit/terraform-azure-ssh-key?ref=v1.0.6" + + algorithm = var.ssh-keys_algorithm + ecdsa_curve = var.ssh-keys_ecdsa_curve + key_name = var.ssh-keys_key_name + name_prefix = var.name_prefix + private_file_permissions = var.ssh-keys_private_file_permissions + public_file_permissions = var.ssh-keys_public_file_permissions + region = var.region + resource_group_name = module.resource_group.name + rsa_bits = var.ssh-keys_rsa_bits + ssh_key = var.ssh-keys_ssh_key + store_key_in_vault = var.ssh-keys_store_key_in_vault + store_path = var.ssh-keys_store_path +} +module "vnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet?ref=v1.1.3" + + address_prefix_count = var.vnet_address_prefix_count + address_prefixes = var.vnet_address_prefixes == null ? null : jsondecode(var.vnet_address_prefixes) + base_security_group_name = var.vnet_base_security_group_name + internal_cidr = var.vnet_internal_cidr + name = var.vnet_name + name_prefix = var.name_prefix + provision = var.vnet_provision + region = var.region + resource_group_name = module.resource_group.name +} +module "vpn-server" { + source = "github.com/cloud-native-toolkit/terraform-azure-vpn-server?ref=v1.0.1" + + admin_username = var.vpn-server_admin_username + bootstrap_script = var.vpn-server_bootstrap_script + client_network = var.vpn-server_client_network + client_network_bits = var.vpn-server_client_network_bits + name_prefix = var.vpn-server_name_prefix + private_dns = var.vpn-server_private_dns == null ? null : jsondecode(var.vpn-server_private_dns) + private_ip_address_allocation_type = var.vpn-server_private_ip_address_allocation_type + private_key_file = module.ssh-keys.private_key_file + private_network_cidrs = var.vpn-server_private_network_cidrs == null ? null : jsondecode(var.vpn-server_private_network_cidrs) + pub_ssh_key_file = module.ssh-keys.pub_key_file + resource_group_name = module.resource_group.name + storage_type = var.vpn-server_storage_type + subnet_id = module.ingress_subnet.id + virtual_network_name = module.vnet.name + vm_public_ip_allocation_method = var.vpn-server_vm_public_ip_allocation_method + vm_public_ip_sku = var.vpn-server_vm_public_ip_sku + vm_size = var.vpn-server_vm_size +} +module "worker_subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + + acl_rules = var.worker_subnet_acl_rules == null ? null : jsondecode(var.worker_subnet_acl_rules) + disable_private_link_endpoint_network_policies = var.worker_subnet_disable_private_link_endpoint_network_policies + disable_private_link_service_network_policies = var.worker_subnet_disable_private_link_service_network_policies + ipv4_cidr_blocks = var.worker_subnet_ipv4_cidr_blocks == null ? null : jsondecode(var.worker_subnet_ipv4_cidr_blocks) + label = var.worker_subnet_label + provision = var.worker_subnet_provision + region = var.region + resource_group_name = module.resource_group.name + service_endpoints = var.worker_subnet_service_endpoints == null ? null : jsondecode(var.worker_subnet_service_endpoints) + subnet_name = var.worker_subnet_subnet_name + vnet_name = module.vnet.name +} diff --git a/2-standard/1-aro/101-azure-vnet-std/output.tf b/2-standard/1-aro/101-azure-vnet-std/output.tf new file mode 100644 index 0000000..c2b1540 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/output.tf @@ -0,0 +1,233 @@ +output "resource_group_name" { + description = "The name of the resource group" + value = module.resource_group.name +} +output "resource_group_id" { + description = "The id of the resource group" + value = module.resource_group.id +} +output "resource_group_group" { + description = "The resource group object" + value = module.resource_group.group +} +output "resource_group_provision" { + description = "Flag indicating whether the resource group was provisioned" + value = module.resource_group.provision +} +output "resource_group_sync" { + description = "Value used to order the provisioning of the resource group" + value = module.resource_group.sync +} +output "resource_group_region" { + description = "the value of resource_group_region" + value = module.resource_group.region +} +output "vnet_name" { + description = "The name of the VNet instance" + value = module.vnet.name +} +output "vnet_id" { + description = "The id of the VNet instance" + value = module.vnet.id +} +output "vnet_crn" { + description = "The CRN for the VNet instance" + value = module.vnet.crn +} +output "vnet_count" { + description = "The number of VPCs created by this module. Always set to 1" + value = module.vnet.count +} +output "vnet_names" { + description = "The name of the vpc instance" + value = module.vnet.names +} +output "vnet_ids" { + description = "The id of the vnet instance" + value = module.vnet.ids +} +output "vnet_addresses" { + description = "The ip address ranges for the VNet" + value = module.vnet.addresses +} +output "master_subnet_count" { + description = "The number of subnets created" + value = module.master_subnet.count +} +output "master_subnet_name" { + description = "The name prefix for the subnets" + value = module.master_subnet.name +} +output "master_subnet_ids" { + description = "List of the ids created" + value = module.master_subnet.ids +} +output "master_subnet_id" { + description = "The id of the first subnet" + value = module.master_subnet.id +} +output "master_subnet_names" { + description = "List of the subnet names" + value = module.master_subnet.names +} +output "master_subnet_subnets" { + description = "Object list of the subnets - id, zone and label." + value = module.master_subnet.subnets +} +output "master_subnet_acl_id" { + description = "Id of the created network security group" + value = module.master_subnet.acl_id +} +output "master_subnet_vnet_name" { + description = "Pass-through of the VNet name associated with the subnets" + value = module.master_subnet.vnet_name +} +output "master_subnet_vnet_id" { + description = "Pass-through of the VNet id associated with the subnets" + value = module.master_subnet.vnet_id +} +output "master_subnet_cidr_blocks" { + description = "List of the CIDR blocks assigned to the subnets" + value = module.master_subnet.cidr_blocks +} +output "worker_subnet_count" { + description = "The number of subnets created" + value = module.worker_subnet.count +} +output "worker_subnet_name" { + description = "The name prefix for the subnets" + value = module.worker_subnet.name +} +output "worker_subnet_ids" { + description = "List of the ids created" + value = module.worker_subnet.ids +} +output "worker_subnet_id" { + description = "The id of the first subnet" + value = module.worker_subnet.id +} +output "worker_subnet_names" { + description = "List of the subnet names" + value = module.worker_subnet.names +} +output "worker_subnet_subnets" { + description = "Object list of the subnets - id, zone and label." + value = module.worker_subnet.subnets +} +output "worker_subnet_acl_id" { + description = "Id of the created network security group" + value = module.worker_subnet.acl_id +} +output "worker_subnet_vnet_name" { + description = "Pass-through of the VNet name associated with the subnets" + value = module.worker_subnet.vnet_name +} +output "worker_subnet_vnet_id" { + description = "Pass-through of the VNet id associated with the subnets" + value = module.worker_subnet.vnet_id +} +output "worker_subnet_cidr_blocks" { + description = "List of the CIDR blocks assigned to the subnets" + value = module.worker_subnet.cidr_blocks +} +output "ingress_subnet_count" { + description = "The number of subnets created" + value = module.ingress_subnet.count +} +output "ingress_subnet_name" { + description = "The name prefix for the subnets" + value = module.ingress_subnet.name +} +output "ingress_subnet_ids" { + description = "List of the ids created" + value = module.ingress_subnet.ids +} +output "ingress_subnet_id" { + description = "The id of the first subnet" + value = module.ingress_subnet.id +} +output "ingress_subnet_names" { + description = "List of the subnet names" + value = module.ingress_subnet.names +} +output "ingress_subnet_subnets" { + description = "Object list of the subnets - id, zone and label." + value = module.ingress_subnet.subnets +} +output "ingress_subnet_acl_id" { + description = "Id of the created network security group" + value = module.ingress_subnet.acl_id +} +output "ingress_subnet_vnet_name" { + description = "Pass-through of the VNet name associated with the subnets" + value = module.ingress_subnet.vnet_name +} +output "ingress_subnet_vnet_id" { + description = "Pass-through of the VNet id associated with the subnets" + value = module.ingress_subnet.vnet_id +} +output "ingress_subnet_cidr_blocks" { + description = "List of the CIDR blocks assigned to the subnets" + value = module.ingress_subnet.cidr_blocks +} +output "nsg_id" { + description = "ID of the created network security group" + value = module.nsg.id +} +output "nsg_name" { + description = "Name of the created network security group" + value = module.nsg.name +} +output "ssh-keys_id" { + description = "Azure vault identification of the stored key" + value = module.ssh-keys.id +} +output "ssh-keys_pub_key" { + description = "Public key" + value = module.ssh-keys.pub_key +} +output "ssh-keys_pub_key_file" { + description = "File path of public key" + value = module.ssh-keys.pub_key_file +} +output "ssh-keys_private_key" { + description = "Private key" + value = module.ssh-keys.private_key + sensitive = true +} +output "ssh-keys_private_key_file" { + description = "File path of the private key" + value = module.ssh-keys.private_key_file +} +output "ssh-keys_path" { + description = "Path to where keys are stored in filesystem" + value = module.ssh-keys.path +} +output "ssh-keys_name" { + description = "Name of the key" + value = module.ssh-keys.name +} +output "vpn-server_id" { + description = "The Azure id of the created VPN server" + value = module.vpn-server.id +} +output "vpn-server_vm_public_ip" { + description = "The public IP address of the created VPN server" + value = module.vpn-server.vm_public_ip +} +output "vpn-server_vm_public_fqdn" { + description = "The FQDN of the public IP address" + value = module.vpn-server.vm_public_fqdn +} +output "vpn-server_admin_username" { + description = "The administrator username of the created VPN server" + value = module.vpn-server.admin_username +} +output "vpn-server_vm_private_ip" { + description = "The private IP address of the created VPN server" + value = module.vpn-server.vm_private_ip +} +output "vpn-server_client_config_file" { + description = "The full path and filename of the created VPN client connection file" + value = module.vpn-server.client_config_file +} diff --git a/2-standard/1-aro/101-azure-vnet-std/providers.tf b/2-standard/1-aro/101-azure-vnet-std/providers.tf new file mode 100644 index 0000000..978f99b --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/providers.tf @@ -0,0 +1,9 @@ + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} \ No newline at end of file diff --git a/2-standard/1-aro/101-azure-vnet-std/terragrunt.hcl b/2-standard/1-aro/101-azure-vnet-std/terragrunt.hcl new file mode 100644 index 0000000..b4cba33 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/terragrunt.hcl @@ -0,0 +1,3 @@ +include "root" { + path = find_in_parent_folders() +} \ No newline at end of file diff --git a/2-standard/1-aro/101-azure-vnet-std/variables.tf b/2-standard/1-aro/101-azure-vnet-std/variables.tf new file mode 100644 index 0000000..260d6b2 --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/variables.tf @@ -0,0 +1,304 @@ +variable "resource_group_name" { + type = string + description = "The name of the resource group" +} +variable "resource_group_provision" { + type = bool + description = "Flag indicating that the resource group should be created" + default = true +} +variable "resource_group_sync" { + type = string + description = "Value used to order the provisioning of the resource group" + default = "" +} +variable "region" { + type = string + description = "The Azure location where the resource group will be provisioned" +} +variable "subscription_id" { + type = string + description = "the value of subscription_id" +} +variable "client_id" { + type = string + description = "the value of client_id" +} +variable "client_secret" { + type = string + description = "the value of client_secret" +} +variable "tenant_id" { + type = string + description = "the value of tenant_id" +} +variable "vnet_name" { + type = string + description = "The name of the vpc instance" + default = "" +} +variable "name_prefix" { + type = string + description = "The name of the vpc resource" + default = "" +} +variable "vnet_provision" { + type = bool + description = "Flag indicating that the instance should be provisioned. If false then an existing instance will be looked up" + default = true +} +variable "vnet_address_prefix_count" { + type = number + description = "The number of ipv4_cidr_blocks" + default = 0 +} +variable "vnet_address_prefixes" { + type = string + description = "List of ipv4 cidr blocks for the address prefixes (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[\"10.0.0.0/20\"]" +} +variable "vnet_base_security_group_name" { + type = string + description = "The name of the base security group. If not provided the name will be based on the vpc name" + default = "" +} +variable "vnet_internal_cidr" { + type = string + description = "The cidr range of the internal network" + default = "10.0.0.0/8" +} +variable "master_subnet_subnet_name" { + type = string + description = "The name of the subnet instance" + default = "" +} +variable "master_subnet_label" { + type = string + description = "Label for the subnets created" + default = "master" +} +variable "master_subnet_provision" { + type = bool + description = "Flag indicating that the subnet should be provisioned. If 'false' then the subnet will be looked up." + default = true +} +variable "master_subnet_ipv4_cidr_blocks" { + type = string + description = "List of ipv4 cidr blocks for the subnets that will be created (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[\"10.0.1.0/24\"]" +} +variable "master_subnet_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[]" +} +variable "master_subnet_service_endpoints" { + type = string + description = "The list of service endpoints for the subnet" + default = "[\"Microsoft.ContainerRegistry\",\"Microsoft.Storage\"]" +} +variable "master_subnet_disable_private_link_endpoint_network_policies" { + type = bool + description = "Flag to disable private link endpoint network policies in the subnet." + default = true +} +variable "master_subnet_disable_private_link_service_network_policies" { + type = bool + description = "Flag to disable private link service network policies in the subnet." + default = true +} +variable "worker_subnet_subnet_name" { + type = string + description = "The name of the subnet instance" + default = "" +} +variable "worker_subnet_label" { + type = string + description = "Label for the subnets created" + default = "worker" +} +variable "worker_subnet_provision" { + type = bool + description = "Flag indicating that the subnet should be provisioned. If 'false' then the subnet will be looked up." + default = true +} +variable "worker_subnet_ipv4_cidr_blocks" { + type = string + description = "List of ipv4 cidr blocks for the subnets that will be created (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[\"10.0.2.0/24\"]" +} +variable "worker_subnet_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[]" +} +variable "worker_subnet_service_endpoints" { + type = string + description = "The list of service endpoints for the subnet" + default = "[\"Microsoft.ContainerRegistry\",\"Microsoft.Storage\"]" +} +variable "worker_subnet_disable_private_link_endpoint_network_policies" { + type = bool + description = "Flag to disable private link endpoint network policies in the subnet." + default = false +} +variable "worker_subnet_disable_private_link_service_network_policies" { + type = bool + description = "Flag to disable private link service network policies in the subnet." + default = false +} +variable "ingress_subnet_subnet_name" { + type = string + description = "The name of the subnet instance" + default = "" +} +variable "ingress_subnet_label" { + type = string + description = "Label for the subnets created" + default = "ingress" +} +variable "ingress_subnet_provision" { + type = bool + description = "Flag indicating that the subnet should be provisioned. If 'false' then the subnet will be looked up." + default = true +} +variable "ingress_subnet_ipv4_cidr_blocks" { + type = string + description = "List of ipv4 cidr blocks for the subnets that will be created (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[\"10.0.3.0/24\"]" +} +variable "ingress_subnet_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[]" +} +variable "ingress_subnet_service_endpoints" { + type = string + description = "The list of service endpoints for the subnet" + default = "[\"Microsoft.ContainerRegistry\"]" +} +variable "ingress_subnet_disable_private_link_endpoint_network_policies" { + type = bool + description = "Flag to disable private link endpoint network policies in the subnet." + default = false +} +variable "ingress_subnet_disable_private_link_service_network_policies" { + type = bool + description = "Flag to disable private link service network policies in the subnet." + default = false +} +variable "nsg_name" { + type = string + description = "Name for network security group - replaces name_prefix (default = \"\")" + default = "" +} +variable "nsg_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[{\"name\":\"ssh-inbound\",\"priority\":\"101\",\"access\":\"Allow\",\"protocol\":\"Tcp\",\"direction\":\"Inbound\",\"source_addr\":\"*\",\"destination_addr\":\"*\",\"source_ports\":\"*\",\"destination_ports\":\"22\"},{\"name\":\"vpn-inbound-tcp\",\"priority\":\"102\",\"access\":\"Allow\",\"protocol\":\"Tcp\",\"direction\":\"Inbound\",\"source_addr\":\"*\",\"destination_addr\":\"*\",\"source_ports\":\"*\",\"destination_ports\":\"443\"},{\"name\":\"vpn-inbound-udp\",\"priority\":\"103\",\"access\":\"Allow\",\"protocol\":\"Udp\",\"direction\":\"Inbound\",\"source_addr\":\"*\",\"destination_addr\":\"*\",\"source_ports\":\"*\",\"destination_ports\":\"1194\"}]" +} +variable "ssh-keys_key_name" { + type = string + description = "Name to give to SSH key" + default = "" +} +variable "ssh-keys_store_path" { + type = string + description = "Path to directory in which to store keys (will default to current working directory)" + default = "" +} +variable "ssh-keys_public_file_permissions" { + type = string + description = "Permissions to be set on public key files (default = 0600)" + default = "0600" +} +variable "ssh-keys_private_file_permissions" { + type = string + description = "Permissions to be set on public key files (default = 0400)" + default = "0400" +} +variable "ssh-keys_store_key_in_vault" { + type = bool + description = "Flag to storage the generated or supplied key in the Azure vault" + default = true +} +variable "ssh-keys_ssh_key" { + type = string + description = "Path to existing public key to be used. Will be created if empty. (Default empty string)" + default = "" +} +variable "ssh-keys_algorithm" { + type = string + description = "Algorithim to be utilized if creating a new key (RSA, ECDSA or ED25519, default = RSA)" + default = "RSA" +} +variable "ssh-keys_rsa_bits" { + type = number + description = "Number of bits to use for RSA key (default = 4096)" + default = 4096 +} +variable "ssh-keys_ecdsa_curve" { + type = string + description = "ECDSA Curve value to be utilized for ECDSA key (P224, P256, P521, default = P224)" + default = "P224" +} +variable "vpn-server_private_network_cidrs" { + type = string + description = "List of CIDRs in the private network reachable via the VPN server." + default = "[\"10.0.0.0/20\"]" +} +variable "vpn-server_private_dns" { + type = string + description = "List of private DNS servers" + default = "[\"168.63.129.16\"]" +} +variable "vpn-server_name_prefix" { + type = string + description = "Name to prefix resources created" + default = "open-vpn" +} +variable "vpn-server_client_network" { + type = string + description = "Network address for VPN clients (default = \"172.27.224.0\")" + default = "172.27.224.0" +} +variable "vpn-server_client_network_bits" { + type = string + description = "Number of netmask bits for the VPN client network (default = \"24\")" + default = "24" +} +variable "vpn-server_private_ip_address_allocation_type" { + type = string + description = "The Azure subnet private ip address alocation type - Dynamic or Static (default = \"Dynamic\")" + default = "Dynamic" +} +variable "vpn-server_admin_username" { + type = string + description = "Username for the admin user (default = \"adminuser\")" + default = "azureuser" +} +variable "vpn-server_bootstrap_script" { + type = string + description = "Path to file with the bootstrap script (default = \"./template/user-data.sh\")" + default = "" +} +variable "vpn-server_vm_size" { + type = string + description = "This is the size of Virtual Machine (defualt = \"Standard_F2\")" + default = "Standard_B1s" +} +variable "vpn-server_storage_type" { + type = string + description = "Storage account type (default = \"StandardSSD_LRS\")" + default = "StandardSSD_LRS" +} +variable "vpn-server_vm_public_ip_sku" { + type = string + description = "Public IP SKU Size (default = \"Standard\")" + default = "Standard" +} +variable "vpn-server_vm_public_ip_allocation_method" { + type = string + description = "The Azure subnet Public ip address alocation type - Dynamic or Static (default = \"Dynamic\")" + default = "Static" +} diff --git a/2-standard/1-aro/101-azure-vnet-std/version.tf b/2-standard/1-aro/101-azure-vnet-std/version.tf new file mode 100644 index 0000000..eb2f15f --- /dev/null +++ b/2-standard/1-aro/101-azure-vnet-std/version.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + } + + } +} \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/105-azure-aro-std.auto.tfvars b/2-standard/1-aro/105-azure-aro-std/105-azure-aro-std.auto.tfvars new file mode 100644 index 0000000..e367246 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/105-azure-aro-std.auto.tfvars @@ -0,0 +1,21 @@ +## resource_group_name: The name of the resource group +#resource_group_name="" + +## region: The Azure location where the resource group will be provisioned +#region="" + +## subscription_id: the value of subscription_id +#subscription_id="" + +## client_id: the value of client_id +#client_id="" + +## client_secret: the value of client_secret +#client_secret="" + +## tenant_id: the value of tenant_id +#tenant_id="" + +## name_prefix: The name of the vpc resource +#name_prefix="" + diff --git a/2-standard/1-aro/105-azure-aro-std/apply.sh b/2-standard/1-aro/105-azure-aro-std/apply.sh new file mode 100755 index 0000000..cc88204 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/apply.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +VARIABLES_FILE="${1}" +if [[ -z "${VARIABLES_FILE}" ]]; then + VARIABLES_FILE="variables.yaml" +fi + +YQ=$(command -v yq4 || command -v yq) +if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g") == "3" ]]; then + echo "yq v4 is required" + exit 1 +fi + +if ! command -v jq 1> /dev/null 2> /dev/null; then + echo "jq is required" + exit 1 +fi + +CREDENTIALS_PROPERTIES="credentials.properties" +TERRAFORM_TFVARS="terraform/terraform.tfvars" + +if [[ -f "${TERRAFORM_TFVARS}" ]]; then + cp "${TERRAFORM_TFVARS}" "${TERRAFORM_TFVARS}.backup" + rm "${TERRAFORM_TFVARS}" +fi + +if [[ -f "${CREDENTIALS_PROPERTIES}" ]]; then + cp "${CREDENTIALS_PROPERTIES}" "${CREDENTIALS_PROPERTIES}.backup" + rm "${CREDENTIALS_PROPERTIES}" +fi +touch "${CREDENTIALS_PROPERTIES}" + +if [[ ! -f "${VARIABLES_FILE}" ]]; then + echo "Variables can be provided in a yaml file passed as the first argument" + echo "" +fi + +TMP_VARIABLES_FILE="${VARIABLES_FILE}.tmp" + +echo "variables: []" > ${TMP_VARIABLES_FILE} + +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" + + local variable_name="TF_VAR_${name}" + + environment_variable=$(env | grep "${variable_name}" | sed -E 's/.*=(.*).*/\1/g') + value="${environment_variable}" + if [[ -f "${VARIABLES_FILE}" ]]; then + value=$(cat "${VARIABLES_FILE}" | NAME="${name}" ${YQ} e -o json '.variables[] | select(.name == env(NAME)) | .value // ""' - | jq -c -r '.') + if [[ -z "${value}" ]]; then + value="${environment_variable}" + fi + fi + + while [[ -z "${value}" ]]; do + echo "Provide a value for '${name}':" + if [[ -n "${description}" ]]; then + echo " ${description}" + fi + sensitive_flag="" + if [[ "${sensitive}" == "true" ]]; then + sensitive_flag="-s" + fi + default_prompt="" + if [[ -n "${default_value}" ]]; then + default_prompt="(${default_value}) " + fi + read -u 1 ${sensitive_flag} -p "> ${default_prompt}" value + value=${value:-$default_value} + done + + output_value=$(echo "${value}" | sed 's/"/\\"/g') + + if [[ "${sensitive}" != "true" ]]; then + echo "${name} = \"${output_value}\"" >> "${TERRAFORM_TFVARS}" + NAME="${name}" VALUE="${value}" ${YQ} e -i -P '.variables += [{"name": env(NAME), "value": env(VALUE)}]' "${TMP_VARIABLES_FILE}" + else + echo "export ${name}=\"${output_value}\"" >> "${CREDENTIALS_PROPERTIES}" + fi +} + +cat "bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while read name; do + variable=$(cat "bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME))' -) + + default_value=$(echo "${variable}" | ${YQ} e -o json '.defaultValue // ""' - | jq -c -r '.') + sensitive=$(echo "${variable}" | ${YQ} e '.sensitive // false' -) + description=$(echo "${variable}" | ${YQ} e '.description // ""' -) + + process_variable "${name}" "${default_value}" "${sensitive}" "${description}" +done + +cat "${VARIABLES_FILE}" | ${YQ} e '.variables[]' -o json - | jq -c '.' | while read var; do + name=$(echo "${var}" | jq -r '.name') + + value=$(echo "${var}" | jq -r '.value // empty') + sensitive=$(echo "${var}" | jq -r '.sensitive') + + bom_var=$(cat bom.yaml | ${YQ} e '.spec.variables[]' -o json - | jq --arg NAME "${name}" -c 'select(.name == $NAME)') + + if [[ -z "${bom_var}" ]]; then + process_variable "${name}" "${value}" "${sensitive}" "" + fi +done + +cp "${TMP_VARIABLES_FILE}" "${VARIABLES_FILE}" +rm "${TMP_VARIABLES_FILE}" + +source credentials.properties + +cd terraform +terraform init +terraform apply diff --git a/2-standard/1-aro/105-azure-aro-std/bom.yaml b/2-standard/1-aro/105-azure-aro-std/bom.yaml new file mode 100644 index 0000000..6e064ba --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/bom.yaml @@ -0,0 +1,75 @@ +apiVersion: cloud.ibm.com/v1alpha1 +kind: BillOfMaterial +metadata: + name: 105-azure-aro-std + labels: + type: infrastructure + platform: azure + code: '105' + annotations: + displayName: Azure Red Hat OpenShift (ARO) Quickstart + description: Azure ARO for Standard Architecture + vpn/required: 'true' +spec: + modules: + - name: azure-resource-group + alias: resource_group + version: v1.1.1 + variables: + - name: provision + value: false + - name: azure-vnet + alias: vnet + version: v1.1.3 + variables: + - name: provision + value: false + - name: azure-vnet-subnets + alias: master-subnet + version: v1.3.9 + variables: + - name: label + value: master + - name: provision + value: false + - name: azure-vnet-subnets + alias: worker-subnet + version: v1.3.9 + variables: + - name: label + value: worker + - name: provision + value: false + - name: azure-aro + alias: cluster + version: v1.0.0 + dependencies: + - name: master-subnet + ref: master-subnet + - name: worker-subnet + ref: worker-subnet + variables: + - name: master_subnet_id + ref: master-subnet + - name: worker_subnet_id + ref: worker-subnet + variables: + - name: resource_group_name + type: string + description: The name of the resource group + - name: region + type: string + description: The Azure location where the resource group will be provisioned + - name: subscription_id + type: string + - name: client_id + type: string + - name: client_secret + type: string + sensitive: true + - name: tenant_id + type: string + - name: name_prefix + type: string + description: The name of the vpc resource + defaultValue: '' diff --git a/2-standard/1-aro/105-azure-aro-std/dependencies.dot b/2-standard/1-aro/105-azure-aro-std/dependencies.dot new file mode 100644 index 0000000..1713015 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/dependencies.dot @@ -0,0 +1,17 @@ +digraph { + rankdir="BT" + "resource_group (azure-resource-group)" +"vnet (azure-vnet)" -> "resource_group (azure-resource-group)" +"vnet (azure-vnet)" +"master-subnet (azure-vnet-subnets)" -> "resource_group (azure-resource-group)" +"master-subnet (azure-vnet-subnets)" -> "vnet (azure-vnet)" +"master-subnet (azure-vnet-subnets)" +"worker-subnet (azure-vnet-subnets)" -> "resource_group (azure-resource-group)" +"worker-subnet (azure-vnet-subnets)" -> "vnet (azure-vnet)" +"worker-subnet (azure-vnet-subnets)" +"cluster (azure-aro)" -> "resource_group (azure-resource-group)" +"cluster (azure-aro)" -> "vnet (azure-vnet)" +"cluster (azure-aro)" -> "master-subnet (azure-vnet-subnets)" +"cluster (azure-aro)" -> "worker-subnet (azure-vnet-subnets)" +"cluster (azure-aro)" + } \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/destroy.sh b/2-standard/1-aro/105-azure-aro-std/destroy.sh new file mode 100755 index 0000000..7c27549 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/destroy.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd "${SCRIPT_DIR}/terraform" +terraform init +terraform destroy -auto-approve diff --git a/2-standard/1-aro/105-azure-aro-std/docs/azure-aro.md b/2-standard/1-aro/105-azure-aro-std/docs/azure-aro.md new file mode 100644 index 0000000..101f5c8 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/docs/azure-aro.md @@ -0,0 +1,180 @@ +# Azure Red Hat OpenShift module + +## Module Overview + +Module creates an Azure RedHat OpenShift (ARO) cluster. It includes the following resources: +- terraform-util-clis (to setup CLI utils for build) +- random_domain +- terraform-azure-resource-group (to create a resource group for the ARO cluster) +- null_resource_aro (creates and destroys the cluster) + +### Software dependencies + +- terraform CLI >= 1.2.6 +- Azure CLI (az) >= 2.39.0 + +### Terraform providers + +- Terraform >= 0.15.0 +- Azure provider >= 3.0.0 + +### Module dependencies + +This module makes use of the output from other modules: +- Azure Resource Group = github.com/cloud-native-toolkit/terraform-azure-resource-group +- Azure VNet - github.com/cloud-native-toolkit/terraform-azure-vnet +- Azure Subnets - github.com/cloud-native-toolkit/terraform-azure-subnets + +## Prerequisites + +### Option 1 - Use a service principal + +The service principal needs the following roles assigned +- In the active directory, application and user administrator permissions + + - User Administrator + 1. From the Azure Active Directory page, go to Roles and administrators. + 1. Find user administrators + 1. Add assignment + + - Application administrator + 1. Select the created service principal and assign role + 1. Find Application administrator + 1. Add assignment + 1. Select the created service principal and assign role + +- In the subscription, application and user administrator + - User Administrator + 1. Go to the subscription page. + 1. Select Access Control (IAM) + 1. Review Role assignments + 1. Add role (+ Add) + 1. Select "Add role assignment" + 1. Search for User Access Administrator + 1. Go to Members + 1. Select Members (+ Select Members) + 1. Choose the service principal + 1. Review and assign + + - Application Administrator + 1. Go to the subscription page. + 1. Select Access Control (IAM) + 1. Review Role assignments + 1. Add role (+ Add) + 1. Select "Add role assignment" + 1. Search for Application Administrator + 1. Go to Members + 1. Select Members (+ Select Members) + 1. Choose the service principal + 1. Review and assign + +### Option 2 - Login with your own user + +Functionality to support using your own user will be provided in a future release. + +## Example Usage + +```hcl-terraform +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group" + + resource_group_name = "mytest-rg" + region = var.region +} + +module "vnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet" + + name_prefix = "mytest" + resource_group_name = module.resource_group.name + region = module.resource_group.region + address_prefixes = ["10.0.0.0/18"] +} + +module "worker-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets" + + resource_group_name = module.resource_group.name + region = module.resource_group.region + vnet_name = module.vnet.name + label = "worker" + ipv4_cidr_blocks = ["10.0.0.0/24"] + acl_rules = [] + service_endpoints = ["Microsoft.ContainerRegistry","Microsoft.Storage"] +} + +module "master-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets" + + resource_group_name = module.resource_group.name + region = module.resource_group.region + vnet_name = module.vnet.name + label = "master" + ipv4_cidr_blocks = ["10.0.1.0/24"] + acl_rules = [] + service_endpoints = ["Microsoft.ContainerRegistry","Microsoft.Storage"] +} + +module "aro" { + source = "github.com/cloud-native-toolkit/terraform-azure-aro" + + name_prefix = "mytest" + + subscription_id = var.azure_subscription_id + tenant_id = var.azure_tenant_id + client_id = var.service_principal_id + client_secret = var.service_principal_secret + + resource_group_name = module.resource_group.name + region = module.resource_group.region + vnet_name = module.vnet.name + master_subnet_id = module.master-subnet.id + worker_subent_id = module.worker-subnet.id +} +``` + +## Variables + +### Inputs + +### Inputs + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| resource_group_name | Mandatory | | The resource group of the network (VNet and subnet) components. A new resource group will be created for the cluster. | +| region | | Manadatory | The Azure region/location where the cluster is to be deployed | +| vnet_name | | Mandatory | The Azure VNet on which to create the cluster | +| worker_subnet_id | | Mandatory | The id of the Azure subnet to attach the worker/compute nodes to | +| master_subnet_id | | Mandatory | The id of the Azure subnet to attach the master/controller nodes to | +| name_prefix | Mandatory | | Name to prefix the created resources | +| subscription_id | Mandatory | | Azure subscription id where the cluster will be installed | +| tenant_id | Mandatory | | Azure tenant id where the cluster will be installed | +| client_id | Mandatory | | The id of the service principal to be used for the cluster creation and ongoing management | +| client_secret | Mandatory | | The secret of the service principal to be used for the cluster creation and ongoing management | +| name | "" | Optional | The name to give to the cluster. If left blank, the name will be generated from the name_prefix | +| name_prefix | "" | Optional | The prefix for the cluster name. If left blank, the network resource group name will be used to derive the cluster name | +| master_flavor | Standard_D8s_v3 | Optional | The VM size for the master/controller nodes | +| flavor | Standard_D4s_v3 | Optional | The VM size for the worker/compute nodes | +| _count | 3 | Optional | The number of worker/compute nodes to be created (min 2) | +| provision | true | Optional | Flag to determine whether to provison the cluster. If false, an existing cluster will be queried | +| disable_public_endpoint | false | Optional | If set true, no public facing endpoints will be provisioned (used for private VNet deployments) | +| pull_secret | "" | Optional | A Red Hat pull secret used to access a Red Hat account. If left blank and no pull secret file is provided, cluster will still deploy, but additional content will not be available | +| pull_secret_file | "" | Optional | Path to a file containing a Red Hat pull secret used to access a Red Hat account. If left blank and no pull secret is provided, cluster will still deploy, but additional content will not be available | +| label | cluster | Optional | Suffix to be added to the name_prefix to derive the cluster name if no name is provided | + +### Outputs + +The module outputs the following values: +| Output | Description | +| -------------------------------- | -------------------------------------------------------------------------- | +| id | The Id of the cluster | +| name | The name of the cluster | +| resource_group_name | The resource group containing the cluster (as opposed to the network resource group) | +| region | The Azure region/location containing the cluster | +| config_file_path | The path to the OpenShift kube config file for the cluster | +| token | The login token for the cluster | +| username | The login username for the cluster | +| password | The login password for the cluster | +| serverURL | The API URL for the cluster | +| platform | Object containing details of the cluster (refer to output.tf for details) | \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/docs/azure-resource-group.md b/2-standard/1-aro/105-azure-aro-std/docs/azure-resource-group.md new file mode 100644 index 0000000..de8ba3c --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/docs/azure-resource-group.md @@ -0,0 +1,55 @@ +# Azure Resource Group + +## Module overview + +### Description + +This module provisions a resource group in Azure. + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- Azure provider >= 2.91.0 + +### Module dependencies + +None + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 2.91.0" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group" + + resource_group_name = var.resource_group_name + region = var.region +} +``` + diff --git a/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet-subnets.md b/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet-subnets.md new file mode 100644 index 0000000..e648a22 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet-subnets.md @@ -0,0 +1,118 @@ +# Azure VNet Subnets + +## Module overview + +### Description + +Module that provisions virtual network subnets on Azure, including the following resources: +- subnet +- network security group +- security group subnet association + +The number of subnets created is controlled by the number of subnet CIDR's supplied and the provision flag. If the provison flag is set to false (it is true by default), the module will not provision anything and will only read the provided subnet name details (use the subnet_name variable to supply the subnet name). + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- Azure provider + +### Module dependencies + +This module makes use of the output from other modules: + +- Resource Group - github.com/cloud-native-toolkit/terraform-azure-resource-group +- VNet - github.com/cloud-native-toolkit/terraform-azure-vnet + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "subnets" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets" + + resource_group_name = module.resource_group.name + region = var.region + vpc_name = module.vpc.name + ipv4_cidr_blocks = ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"] + acl_rules = [{ + name = "ssh-inbound" + action = "Allow" + direction = "Inbound" + source = "*" + destination = "*" + tcp = { + destination_port_range = "22" + source_port_range = "*" + } + }, { + name = "internal-only" + action = "Allow" + direction = "Inbound" + source = "10.0.0.0/16" + destination = "10.0.0.0/24" + udp = { + destination_port_range = "1024 - 2048" + source_port_range = "*" + } + }] +} +``` + +## Input Variables + +This module has the following input variables: +| Variable | Mandatory / Optional | Default Value | Description | +| -------------------------------- | --------------| ------------------ | ----------------------------------------------------------------------------- | +| resource_group_name | Mandatory | | The resource group into which to deploy or query | +| region | Mandatory | | Region into which to deploy or query | +| vnet_name | Mandatory | | Name of the VNet into which to deploy or query | +| subnet_name | Optional | "" | Name of an existing subnet to query | +| label | Optional | "" | Label to use in subnet names | +| provision | Optional | true | Flag to provision new resources or query existing if false | +| ipv4_cidr_blocks | Optional | [] | List of CIDRs for subnets to be created | +| acl_rules | Optional | [] | List of rules to create and associate with the subent(s) | +| service_endpoints | Optional | Microsoft.ContainerRegistry | List of service endpoints for the subnet(s)| +| disable_private_link_endpoint_network_policies | Optional | false | Flag to disable private link endpoint network policies in the subnet(s) | +| disable_private_link_service_network_policies | Optional | false | Flag to disable private link service network policies in the subnet(s) | + +## Output Variables + +This module has the following output variables: +| Variable | Description | +| -------------------------------- | ----------------------------------------------------------------------------- | +| id | The Azure identification string of the created RTB | +| name | The name of the subnet if creating only one | +| count | The number of subnets created or queried | +| ids | List of the ids of the created subnets | +| id | Id of the first created subnet | +| names | List of the names of the created subnets | +| subnets | Object list for the created subnets | +| acl_id | Id of the created network security group | +| vnet_name | Name of the VNet where the subnets were provisioned (passthrough) | +| vnet_id | Id of the VNet where the subnets were provisoned | +| cidr_block | The list of CIDRs assigned to the subnets (passthrough) | diff --git a/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet.md b/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet.md new file mode 100644 index 0000000..5eeda7e --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet.md @@ -0,0 +1,59 @@ +# Azure Virtual Network + +## Module overview + +### Description + +Module to provision a virtual network on Azure + +**Note:** This module follows the Terraform conventions regarding how provider configuration is defined within the Terraform template and passed into the module - https://www.terraform.io/docs/language/modules/develop/providers.html. The default provider configuration flows through to the module. If different configuration is required for a module, it can be explicitly passed in the `providers` block of the module - https://www.terraform.io/docs/language/modules/develop/providers.html#passing-providers-explicitly. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v1.2.7 + +#### Terraform providers + +- Azure provider >= 3.0.0 + +### Module dependencies + +This module makes use of the output from other modules: + +- Resource group - github.com/cloud-native-toolkit/terraform-azure-resource-group + +### Example usage + +```hcl-terraform +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "=3.0.0" + } + } +} + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} + +module "vpc" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet" + + resource_group_name = module.resource_group.name + region = var.region + name_prefix = var.name_prefix + address_prefix_count = 1 + address_prefixes = ["10.0.0.0/16"] +} +``` diff --git a/2-standard/1-aro/105-azure-aro-std/main.tf b/2-standard/1-aro/105-azure-aro-std/main.tf new file mode 100644 index 0000000..49d4ea7 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/main.tf @@ -0,0 +1,48 @@ +module "resource_group" { + source = "github.com/cloud-native-toolkit/terraform-azure-resource-group?ref=v1.1.1" + + provision = var.resource_group_provision + region = var.region + resource_group_name = var.resource_group_name + sync = var.resource_group_sync +} +module "vnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-vnet?ref=v1.1.3" + + address_prefix_count = var.vnet_address_prefix_count + address_prefixes = var.vnet_address_prefixes == null ? null : jsondecode(var.vnet_address_prefixes) + base_security_group_name = var.vnet_base_security_group_name + internal_cidr = var.vnet_internal_cidr + name = var.vnet_name + name_prefix = var.name_prefix + provision = var.vnet_provision + region = var.region + resource_group_name = module.resource_group.name +} + +// Below custom pending bug fix in subnet module + +module "cluster" { + source = "github.com/cloud-native-toolkit/terraform-azure-aro?ref=v1.0.0" + + name_prefix = var.name_prefix + + client_id = var.client_id + client_secret = var.client_secret + subscription_id = var.subscription_id + tenant_id = var.tenant_id + + disable_public_endpoint = true + + pull_secret = var.pull_secret + + disk_size = var.cluster_disk_size + flavor = var.cluster_flavor + master_flavor = var.cluster_master_flavor + + region = module.resource_group.region + resource_group_name = module.resource_group.name + vnet_name = module.vnet.name + master_subnet_id = var.master_subnet_id + worker_subnet_id = var.worker_subnet_id +} \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/output.tf b/2-standard/1-aro/105-azure-aro-std/output.tf new file mode 100644 index 0000000..7423b09 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/output.tf @@ -0,0 +1,51 @@ + +output "cluster_id" { + description = "ID of the created cluster" + value = module.cluster.id +} +output "cluster_name" { + description = "Name of the cluster" + value = module.cluster.name +} +output "cluster_resource_group_name" { + description = "Name of the resource group containing the cluster." + value = module.cluster.resource_group_name +} +output "cluster_region" { + description = "Region containing the cluster." + value = module.cluster.region +} +output "cluster_config_file_path" { + description = "Path to the config file for the cluster" + value = module.cluster.config_file_path +} +output "cluster_token" { + description = "Login token for the cluster" + value = module.cluster.token +} +output "cluster_username" { + description = "Username for the cluster" + value = module.cluster.username +} +output "cluster_password" { + description = "Password for the cluster" + value = module.cluster.password + sensitive = true +} +output "cluster_serverURL" { + description = "The URL used to connect to the API of the cluster" + value = module.cluster.serverURL +} +output "cluster_platform" { + description = "Configuration values for the created cluster platform" + value = module.cluster.platform + sensitive = true +} +output "cluster_sync" { + description = "Value used to sync downstream modules" + value = module.cluster.sync +} +output "cluster_total_worker_count" { + description = "The total number of workers for the cluster. (subnets * number of workers)" + value = module.cluster.total_worker_count +} diff --git a/2-standard/1-aro/105-azure-aro-std/providers.tf b/2-standard/1-aro/105-azure-aro-std/providers.tf new file mode 100644 index 0000000..978f99b --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/providers.tf @@ -0,0 +1,9 @@ + +provider "azurerm" { + features {} + + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id +} \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/terragrunt.hcl b/2-standard/1-aro/105-azure-aro-std/terragrunt.hcl new file mode 100644 index 0000000..17c2f14 --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/terragrunt.hcl @@ -0,0 +1,32 @@ +include "root" { + path = find_in_parent_folders() +} + +locals { + dependencies = yamldecode(file("${get_parent_terragrunt_dir()}/layers.yaml")) + + dep_101 = local.dependencies.names_101 + mock_101 = local.dependencies.mock_101 + cluster_config_path = fileexists("${get_parent_terragrunt_dir()}/${local.dep_101}/terragrunt.hcl") ? "${get_parent_terragrunt_dir()}/${local.dep_101}" : "${get_parent_terragrunt_dir()}/.mocks/${local.mock_101}" + +} + +dependency "vnet" { + config_path = local.cluster_config_path + skip_outputs = false + + mock_outputs_allowed_terraform_commands = ["init","validate","plan"] + mock_outputs = { + resource_group_name = "fake-rg" + vnet_name = "fake-vnet" + master_subnet_name = "fake-master" + worker_subnet_name = "fake-worker" + } +} + +inputs = { + resource_group_name = dependency.vnet.outputs.resource_group_name + vnet_name = dependency.vnet.outputs.vnet_name + master_subnet_id = dependency.vnet.outputs.master_subnet_id + worker_subnet_id = dependency.vnet.outputs.worker_subnet_id +} \ No newline at end of file diff --git a/2-standard/1-aro/105-azure-aro-std/variables.tf b/2-standard/1-aro/105-azure-aro-std/variables.tf new file mode 100644 index 0000000..ed3fd1d --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/variables.tf @@ -0,0 +1,223 @@ +variable "master_subnet_id" { + type = string + description = "The id of the subnet instance" +} +variable "worker_subnet_id" { + type = string + description = "The id of the subnet instance" +} +variable "pull_secret" { + type = string + description = "The contents of the pull secret needed to access Red Hat content. The contents can either be provided directly or passed through the `pull_secret_file` variable" + default = "" +} + + +variable "resource_group_name" { + type = string + description = "The name of the resource group" +} +variable "resource_group_provision" { + type = bool + description = "Flag indicating that the resource group should be created" + default = false +} +variable "resource_group_sync" { + type = string + description = "Value used to order the provisioning of the resource group" + default = "" +} +variable "region" { + type = string + description = "The Azure location where the resource group will be provisioned" +} +variable "subscription_id" { + type = string + description = "the value of subscription_id" +} +variable "client_id" { + type = string + description = "the value of client_id" +} +variable "client_secret" { + type = string + description = "the value of client_secret" +} +variable "tenant_id" { + type = string + description = "the value of tenant_id" +} +variable "vnet_name" { + type = string + description = "The name of the vpc instance" + default = "" +} +variable "name_prefix" { + type = string + description = "The name of the vpc resource" +} +variable "vnet_provision" { + type = bool + description = "Flag indicating that the instance should be provisioned. If false then an existing instance will be looked up" + default = false +} +variable "vnet_address_prefix_count" { + type = number + description = "The number of ipv4_cidr_blocks" + default = 0 +} +variable "vnet_address_prefixes" { + type = string + description = "List of ipv4 cidr blocks for the address prefixes (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[]" +} +variable "vnet_base_security_group_name" { + type = string + description = "The name of the base security group. If not provided the name will be based on the vpc name" + default = "" +} +variable "vnet_internal_cidr" { + type = string + description = "The cidr range of the internal network" + default = "10.0.0.0/8" +} +variable "master-subnet_subnet_name" { + type = string + description = "The name of the subnet instance" + default = "" +} +variable "master-subnet_label" { + type = string + description = "Label for the subnets created" + default = "master" +} +variable "master-subnet_provision" { + type = bool + description = "Flag indicating that the subnet should be provisioned. If 'false' then the subnet will be looked up." + default = false +} +variable "master-subnet_ipv4_cidr_blocks" { + type = string + description = "List of ipv4 cidr blocks for the subnets that will be created (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[]" +} +variable "master-subnet_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[]" +} +variable "master-subnet_service_endpoints" { + type = string + description = "The list of service endpoints for the subnet" + default = "[\"Microsoft.ContainerRegistry\"]" +} +variable "master-subnet_disable_private_link_endpoint_network_policies" { + type = bool + description = "Flag to disable private link endpoint network policies in the subnet." + default = false +} +variable "master-subnet_disable_private_link_service_network_policies" { + type = bool + description = "Flag to disable private link service network policies in the subnet." + default = false +} +variable "worker-subnet_subnet_name" { + type = string + description = "The name of the subnet instance" + default = "" +} +variable "worker-subnet_label" { + type = string + description = "Label for the subnets created" + default = "worker" +} +variable "worker-subnet_provision" { + type = bool + description = "Flag indicating that the subnet should be provisioned. If 'false' then the subnet will be looked up." + default = false +} +variable "worker-subnet_ipv4_cidr_blocks" { + type = string + description = "List of ipv4 cidr blocks for the subnets that will be created (e.g. ['10.10.10.0/24']). If you are providing cidr blocks then a value must be provided for each of the subnets. If you don't provide cidr blocks for each of the subnets then values will be generated using the {ipv4_address_count} value." + default = "[]" +} +variable "worker-subnet_acl_rules" { + type = string + description = "List of rules to set on the subnet access control list" + default = "[]" +} +variable "worker-subnet_service_endpoints" { + type = string + description = "The list of service endpoints for the subnet" + default = "[\"Microsoft.ContainerRegistry\"]" +} +variable "worker-subnet_disable_private_link_endpoint_network_policies" { + type = bool + description = "Flag to disable private link endpoint network policies in the subnet." + default = false +} +variable "worker-subnet_disable_private_link_service_network_policies" { + type = bool + description = "Flag to disable private link service network policies in the subnet." + default = false +} +variable "cluster_openshift_version" { + type = string + description = "The version of the openshift cluster" + default = "4.8.11" +} +variable "cluster_master_flavor" { + type = string + description = "The size of the VMs for the master nodes" + default = "Standard_D8s_v3" +} +variable "cluster_flavor" { + type = string + description = "The size of the VMs for the worker nodes" + default = "Standard_D4s_v3" +} +variable "cluster__count" { + type = number + description = "The number of compute worker nodes" + default = 3 +} +variable "cluster_os_type" { + type = string + description = "The type of os for the master and worker nodes" + default = "Linux" +} +variable "cluster_provision" { + type = bool + description = "Flag indicating the cluster should be provisioned. If the value is false then an existing cluster will be looked up" + default = true +} +variable "cluster_name" { + type = string + description = "The name of the ARO cluster. If empty the name will be derived from the name prefix" + default = "" +} +variable "cluster_auth_group_id" { + type = string + description = "The id of the auth group for cluster admins" + default = "" +} +variable "cluster_disable_public_endpoint" { + type = bool + description = "Flag to make the cluster private only" + default = false +} +variable "cluster_disk_size" { + type = number + description = "The size in GB of the disk for each worker node" + default = 128 +} +variable "cluster_pull_secret_file" { + type = string + description = "Name of the file containing the pull secret needed to access Red Hat content. The contents can either be provided in this file or directly via the `pull_secret` variable" + default = "" +} +variable "cluster_label" { + type = string + description = "The label used to generate the cluster name" + default = "cluster" +} diff --git a/2-standard/1-aro/105-azure-aro-std/version.tf b/2-standard/1-aro/105-azure-aro-std/version.tf new file mode 100644 index 0000000..eb2f15f --- /dev/null +++ b/2-standard/1-aro/105-azure-aro-std/version.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + } + + } +} \ No newline at end of file diff --git a/2-standard/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars b/2-standard/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars new file mode 100644 index 0000000..c46b96f --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars @@ -0,0 +1,27 @@ +## config_banner_text: The text that will appear in the top banner in the cluster +#config_banner_text="" + +## server_url: The url for the OpenShift api +#server_url="" + +## cluster_login_token: Token used for authentication +#cluster_login_token="" + +## gitops_repo_host: The host for the git repository. The git host used can be a GitHub, GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If the host is null assumes in-cluster Gitea instance will be used. +#gitops_repo_host="" + +## gitops_repo_org: The org/group where the git repository exists/will be provisioned. If the value is left blank then the username org will be used. +#gitops_repo_org="" + +## gitops_repo_project: The project that will be used for the git repo. (Primarily used for Azure DevOps repos) +#gitops_repo_project="" + +## gitops_repo_username: The username of the user with access to the repository +#gitops_repo_username="" + +## gitops_repo_token: The personal access token used to access the repository +#gitops_repo_token="" + +## gitops_repo_repo: The short name of the repository (i.e. the part after the org/group name) +#gitops_repo_repo="" + diff --git a/2-standard/1-aro/200-openshift-gitops/apply.sh b/2-standard/1-aro/200-openshift-gitops/apply.sh new file mode 100755 index 0000000..e64c76a --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/apply.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +VARIABLES_FILE="${1}" +if [[ -z "${VARIABLES_FILE}" ]]; then + VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" +fi + +YQ=$(command -v yq4 || command -v yq) +if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g") == "3" ]]; then + echo "yq v4 is required" + exit 1 +fi + +if [[ -f "${SCRIPT_DIR}/terraform/terraform.tfvars" ]]; then + cp "${SCRIPT_DIR}/terraform/terraform.tfvars" "${SCRIPT_DIR}/terraform/terraform.tfvars.backup" + rm "${SCRIPT_DIR}/terraform/terraform.tfvars" +fi + +if [[ ! -f "${VARIABLES_FILE}" ]]; then + echo "Variables can be provided in a yaml file passed as the first argument" + echo "" +fi + +TMP_VARIABLES_FILE="${VARIABLES_FILE}.tmp" + +echo "variables: []" > ${TMP_VARIABLES_FILE} + +cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while read name; do + default_value=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .defaultValue // ""' -) + sensitive=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .sensitive // false' -) + description=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .description // ""' -) + + variable_name="TF_VAR_${name}" + + environment_variable=$(env | grep "${variable_name}" | sed -E 's/.*=(.*).*/\1/g') + value="${environment_variable}" + if [[ -f "${VARIABLES_FILE}" ]]; then + value=$(cat "${VARIABLES_FILE}" | NAME="${name}" ${YQ} e '.variables[] | select(.name == env(NAME)) | .value // ""' -) + if [[ -z "${value}" ]]; then + value="${environment_variable}" + fi + fi + + while [[ -z "${value}" ]]; do + echo "Provide a value for '${name}':" + if [[ -n "${description}" ]]; then + echo " ${description}" + fi + sensitive_flag="" + if [[ "${sensitive}" == "true" ]]; then + sensitive_flag="-s" + fi + default_prompt="" + if [[ -n "${default_value}" ]]; then + default_prompt="(${default_value}) " + fi + read -u 1 ${sensitive_flag} -p "> ${default_prompt}" value + value=${value:-$default_value} + done + + echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + if [[ "${sensitive}" != "true" ]]; then + NAME="${name}" VALUE="${value}" ${YQ} e -i -P '.variables += [{"name": env(NAME), "value": env(VALUE)}]' "${TMP_VARIABLES_FILE}" + fi +done + +cp "${TMP_VARIABLES_FILE}" "${VARIABLES_FILE}" +rm "${TMP_VARIABLES_FILE}" + +cd ${SCRIPT_DIR}/terraform +terraform init +terraform apply diff --git a/2-standard/1-aro/200-openshift-gitops/bom.yaml b/2-standard/1-aro/200-openshift-gitops/bom.yaml new file mode 100644 index 0000000..d77ae60 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/bom.yaml @@ -0,0 +1,102 @@ +apiVersion: cloud.ibm.com/v1alpha1 +kind: BillOfMaterial +metadata: + name: 200-openshift-gitops + labels: + type: software + code: '200' + annotations: + displayName: OpenShift GitOps Bootstrap + description: >- + Provisions OpenShift GitOps (ArgoCD) into an existing cluster and + bootstraps it to a gitops repository + vpn/required: 'true' +spec: + modules: + - name: gitops-cluster-config + alias: config + version: v1.1.1 + - name: ocp-login + alias: cluster + version: v1.6.0 + - name: namespace + alias: gitea_namespace + version: v3.2.3 + variables: + - name: name + value: gitea + - name: gitea + alias: gitea + version: v0.5.0 + dependencies: + - id: namespace + ref: gitea_namespace + - name: gitops-repo + alias: gitops_repo + version: v1.22.1 + - name: argocd-bootstrap + alias: argocd-bootstrap + version: v1.12.0 + variables: + - name: create_webhook + value: true + - name: gitops-console-link-job + alias: gitops-console-link-job + version: v1.5.1 + - name: gitops-namespace + alias: toolkit_namespace + version: v1.12.2 + default: true + variables: + - name: name + value: toolkit + - name: util-clis + version: v1.17.2 + - name: olm + version: v1.3.2 + - name: sealed-secret-cert + version: v1.0.1 + variables: + - name: config_banner_text + type: string + description: The text that will appear in the top banner in the cluster + - name: server_url + type: string + description: The url for the OpenShift api + - name: cluster_login_token + type: string + description: Token used for authentication + sensitive: true + - name: gitops_repo_host + type: string + description: >- + The host for the git repository. The git host used can be a GitHub, + GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If + the host is null assumes in-cluster Gitea instance will be used. + defaultValue: '' + - name: gitops_repo_org + type: string + description: >- + The org/group where the git repository exists/will be provisioned. If + the value is left blank then the username org will be used. + defaultValue: '' + - name: gitops_repo_project + type: string + description: >- + The project that will be used for the git repo. (Primarily used for + Azure DevOps repos) + defaultValue: '' + - name: gitops_repo_username + type: string + description: The username of the user with access to the repository + defaultValue: '' + - name: gitops_repo_token + type: string + description: The personal access token used to access the repository + defaultValue: '' + sensitive: true + - name: gitops_repo_repo + type: string + description: >- + The short name of the repository (i.e. the part after the org/group + name) diff --git a/2-standard/1-aro/200-openshift-gitops/dependencies.dot b/2-standard/1-aro/200-openshift-gitops/dependencies.dot new file mode 100644 index 0000000..89b4ec2 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/dependencies.dot @@ -0,0 +1,30 @@ +digraph { + rankdir="BT" + "config (gitops-cluster-config)" -> "gitops_repo (gitops-repo)" +"config (gitops-cluster-config)" -> "toolkit_namespace (gitops-namespace)" +"config (gitops-cluster-config)" +"gitops_repo (gitops-repo)" -> "sealed-secret-cert (sealed-secret-cert)" +"gitops_repo (gitops-repo)" -> "gitea (gitea)" +"gitops_repo (gitops-repo)" +"sealed-secret-cert (sealed-secret-cert)" +"gitea (gitea)" -> "cluster (ocp-login)" +"gitea (gitea)" -> "olm (olm)" +"gitea (gitea)" -> "gitea_namespace (namespace)" +"gitea (gitea)" +"cluster (ocp-login)" +"olm (olm)" -> "cluster (ocp-login)" +"olm (olm)" +"gitea_namespace (namespace)" -> "cluster (ocp-login)" +"gitea_namespace (namespace)" +"toolkit_namespace (gitops-namespace)" -> "gitops_repo (gitops-repo)" +"toolkit_namespace (gitops-namespace)" +"argocd-bootstrap (argocd-bootstrap)" -> "cluster (ocp-login)" +"argocd-bootstrap (argocd-bootstrap)" -> "olm (olm)" +"argocd-bootstrap (argocd-bootstrap)" -> "gitops_repo (gitops-repo)" +"argocd-bootstrap (argocd-bootstrap)" -> "sealed-secret-cert (sealed-secret-cert)" +"argocd-bootstrap (argocd-bootstrap)" +"gitops-console-link-job (gitops-console-link-job)" -> "gitops_repo (gitops-repo)" +"gitops-console-link-job (gitops-console-link-job)" -> "toolkit_namespace (gitops-namespace)" +"gitops-console-link-job (gitops-console-link-job)" +"util-clis (util-clis)" + } \ No newline at end of file diff --git a/2-standard/1-aro/200-openshift-gitops/destroy.sh b/2-standard/1-aro/200-openshift-gitops/destroy.sh new file mode 100755 index 0000000..7c27549 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/destroy.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd "${SCRIPT_DIR}/terraform" +terraform init +terraform destroy -auto-approve diff --git a/2-standard/1-aro/200-openshift-gitops/docs/argocd-bootstrap.md b/2-standard/1-aro/200-openshift-gitops/docs/argocd-bootstrap.md new file mode 100644 index 0000000..539a41a --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/argocd-bootstrap.md @@ -0,0 +1,55 @@ +# ArgoCD Bootstrap module + +Module that provisions the OpenShift CI/CD tools (ArgoCD, Tekton, and Kube Seal) in the target cluster and bootstraps the ArgoCD environment with a GitOps repository. This module assumes that a direct connection to the cluster is availble in order to deploy the services and configure the ArgoCD instance. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v15 + +### Terraform providers + +None + +## Module dependencies + +This module makes use of the output from other modules: + +- Cluster + - github.com/cloud-native-toolkit/terraform-ibm-container-platform + - github.com/cloud-native-toolkit/terraform-ibm-ocp-vpc + - github.com/cloud-native-toolkit/terraform-k8s-ocp-cluster + - github.com/cloud-native-toolkit/terraform-ocp-login +- OLM + - github.com/cloud-native-toolkit/terraform-k8s-olm +- GitOps + - github.com/cloud-native-toolkit/terraform-tools-gitops +- Sealed Secret Cert + - github.com/cloud-native-toolkit/terraform-util-sealed-secret-cert + +## Example usage + +[Refer the test cases for this module](test/stages/stage2-argocd-bootstrap.tf) + +```hcl-terraform +module "argocd-bootsrap" { + source = "github.com/cloud-native-toolkit/terraform-tools-argocd-bootstrap.git" + + cluster_type = module.dev_cluster.platform.type_code + ingress_subdomain = module.dev_cluster.platform.ingress + cluster_config_file = module.dev_cluster.config_file_path + olm_namespace = module.dev_software_olm.olm_namespace + operator_namespace = module.dev_software_olm.target_namespace + gitops_repo_url = module.gitops.config_repo_url + git_username = module.gitops.config_username + git_token = module.gitops.config_token + bootstrap_path = module.gitops.bootstrap_path + sealed_secret_cert = module.cert.cert + sealed_secret_private_key = module.cert.private_key + create_webhook = true +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/gitea.md b/2-standard/1-aro/200-openshift-gitops/docs/gitea.md new file mode 100644 index 0000000..a99e963 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/gitea.md @@ -0,0 +1,32 @@ +# Gitea terraform module + +![Latest release](https://img.shields.io/github/v/release/ibm-garage-cloud/terraform-tools-gitea?sort=semver) ![Verify and release module](https://github.com/ibm-garage-cloud/terraform-tools-gitea/workflows/Verify%20and%20release%20module/badge.svg) + +Installs Gitea in an Openshift 4.x cluster via the [Red Hat GPTE operator](https://github.com/redhat-gpte-devopsautomation/gitea-operator). This will **NOT** install Gitea in a vanilla Kubernetes cluster. + +## Software dependencies + +The module depends on the following software components: + +- terraform v12 +- kubectl + +## Module dependencies + +- Cluster +- OLM + +## Example usage + +```hcl-terraform +module "dev_tools_gitea" { + source = "github.com/ibm-garage-cloud/terraform-tools-gitea.git?ref=v1.0.0" + + cluster_config_file = module.dev_cluster.config_file_path + cluster_type = module.dev_cluster.type + olm_namespace = module.dev_software_olm.olm_namespace + operator_namespace = module.dev_software_olm.target_namespace + instance_namespace = module.dev_cluster_namespaces.tools_namespace_name + name = "gitea" +} +``` diff --git a/2-standard/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md b/2-standard/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md new file mode 100644 index 0000000..8079c97 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md @@ -0,0 +1,39 @@ +# Cluster config gitops module + +Module to populate a gitops repository with base configuration of the Red Hat OpenShift cluster (notification banner, help menus, etc). + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v14 +- kubectl + +### Terraform providers + +None + +## Module dependencies + +This module makes use of the output from other modules: + +- Gitops - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + +## Example usage + +```hcl-terraform +module "cluster-config" { + source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config.git" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + server_name = module.gitops.server_name + namespace = module.gitops_namespace.name + kubeseal_cert = module.argocd-bootstrap.sealed_secrets_cert + banner_text = var.banner_text +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/gitops-console-link-job.md b/2-standard/1-aro/200-openshift-gitops/docs/gitops-console-link-job.md new file mode 100644 index 0000000..4d25cc8 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/gitops-console-link-job.md @@ -0,0 +1,41 @@ +# Console Link Cronjob module + +Module that populates gitops repository with the Console Link Cronjob chart from https://charts.cloudnativetoolkit.dev. The chart deploys a cron job into a cluster that runs periodically (every 5 minutes by default) looking for matching resources and creating cron jobs and config maps with the information. The matching resources include routes with the `console-link.cloud-native-toolkit.dev/enabled=true` label and `logdna-agent` and `sysdig-agent` daemonsets. + +This module uses the following Helm Charts from toolkit-charts( https://charts.cloudnativetoolkit.dev ) : https://github.com/cloud-native-toolkit/toolkit-charts/blob/main/stable/console-link-cronjob/README.md + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git.git + +## Example usage + +```hcl-terraform +module "console_link_job" { + source = "github.com/cloud-native-toolkit/terraform-gitops-console-link-job.git" + + config_repo = module.gitops.config_repo + config_token = module.gitops.config_token + config_paths = module.gitops.config_paths + config_projects = module.gitops.config_projects + application_repo = module.gitops.application_repo + application_token = module.gitops.application_token + application_paths = module.gitops.application_paths +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/gitops-namespace.md b/2-standard/1-aro/200-openshift-gitops/docs/gitops-namespace.md new file mode 100644 index 0000000..374abd1 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/gitops-namespace.md @@ -0,0 +1,41 @@ +# Namespace gitops config + +Module to configure a GitOps repo to provision a namespace + + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- git + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps repo - github.com/cloud-native-toolkit/terraform-tools-gitops.git + +## Example usage + +```hcl-terraform +module "gitops_namespace" { + source = "github.com/ibm-garage-cloud/terraform-gitops-namespace.git" + + config_repo = module.gitops.config_repo + config_token = module.gitops.config_token + config_paths = module.gitops.config_paths + application_repo = module.gitops.application_repo + application_token = module.gitops.application_token + application_paths = module.gitops.application_paths + name = var.namespace + create_operator_group = false +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/gitops-repo.md b/2-standard/1-aro/200-openshift-gitops/docs/gitops-repo.md new file mode 100644 index 0000000..37846fd --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/gitops-repo.md @@ -0,0 +1,56 @@ +# GitOps repo module + +Module that prepares a GitOps repo for use with ArgoCD. If the `provision` flag is `true` then a new git repo will be provisioned. If not, the provided repo name is expected to already exist. + +After cloning the git repo, an initial directory structure is set up along with bootstrap configuration to perform the initial setup of ArgoCD. + +## Supported git servers + +The module supports creating a repository in one of six different git servers: + +- GitHub +- GitHub Enterprise +- Gitlab +- Bitbucket +- Gitea +- Azure DevOps + +The selection of the git server type is determined by the value provided for the `host`. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- git + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- None + +## Example usage + +```hcl-terraform +module "git" { + source = "github.com/cloud-native-toolkit/terraform-tools-gitops" + + host = var.git_host + org = var.git_org + repo = var.git_repo + username = var.git_username + token = var.git_token + project = var.git_project + gitops_namespace = var.gitops_namespace + sealed_secrets_cert = module.cert.cert + strict = var.gitops_strict +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/namespace.md b/2-standard/1-aro/200-openshift-gitops/docs/namespace.md new file mode 100644 index 0000000..7e8c0d6 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/namespace.md @@ -0,0 +1,39 @@ +# Create Namespaces terraform module + +Creates the namespace with the provided name in the cluster. The namespace and +its contents will be destroyed first before creating the new namespace. Also, the `cloud-config` and +`cloud-access` configmap and secret will be copied from the default namespace into the new +namespace. + + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v12 +- kubectl + +### Terraform providers + +- null (provided by Terraform) + +## Module dependencies + +This module makes use of the output from other modules: + +- Cluster - github.com/ibm-garage-cloud/terraform-ibm-container-platform.git + +## Example usage + +```hcl-terraform +module "namespace" { + source = "github.com/ibm-garage-cloud/terraform-k8s-namespace.git" + + cluster_config_file_path = module.dev_cluster.config_file_path + name = var.namespace +} +``` + + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/ocp-login.md b/2-standard/1-aro/200-openshift-gitops/docs/ocp-login.md new file mode 100644 index 0000000..6e4ad22 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/ocp-login.md @@ -0,0 +1,36 @@ +# OCP Login + +Terraform module to log into a cluster and write the credentials into the kube config file. The file path is output by the module. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v0.15 + +### Terraform providers + +None + +## Module dependencies + +None + +## Example usage + +```hcl-terraform +module "dev_tools_argocd" { + source = "github.com/ibm-garage-cloud/terraform-tools-argocd.git?ref=v1.0.0" + + cluster_config_file = module.dev_cluster.config_file_path + cluster_type = module.dev_cluster.type + app_namespace = module.dev_cluster_namespaces.tools_namespace_name + ingress_subdomain = module.dev_cluster.ingress_hostname + olm_namespace = module.dev_software_olm.olm_namespace + operator_namespace = module.dev_software_olm.target_namespace + name = "argocd" +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/olm.md b/2-standard/1-aro/200-openshift-gitops/docs/olm.md new file mode 100644 index 0000000..4616b71 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/olm.md @@ -0,0 +1,29 @@ +# Operator Lifecycle Manager module + +Installs Operator Lifecycle Manager (OLM) into a cluster. However, if the cluster is OpenShift 4.x +and already has OLM installed then the module does not install anything. It can still be used to export +the olm namespaces for use by downstream modules. + +## Example usage + +```hcl-terraform +module "dev_software_olm_release" { + source = "github.com/ibm-garage-cloud/garage-terraform-modules.git//self-managed/software/operator-lifecycle-manager?ref=olm" + + cluster_config_file = "~/.kube/config" + cluster_version = "3.11" + cluster_type = "ocp3" +} +``` + +Another example + +```hcl-terraform +module "dev_software_olm_release" { + source = "github.com/ibm-garage-cloud/garage-terraform-modules.git//self-managed/software/operator-lifecycle-manager?ref=olm" + + cluster_config_file = module.dev_cluster.config_file_path + cluster_version = module.dev_cluster.version + cluster_type = var.cluster_type +} +``` diff --git a/2-standard/1-aro/200-openshift-gitops/docs/sealed-secret-cert.md b/2-standard/1-aro/200-openshift-gitops/docs/sealed-secret-cert.md new file mode 100644 index 0000000..7f81a1e --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/sealed-secret-cert.md @@ -0,0 +1,38 @@ +# Sealed Secret Cert module + +Module to collect or create a certificate and private key used with the sealed secrets service. The sealed secrets service +is used to store confidential information in a GitOps repository as encrypted SealedSecret resources. When the SealedSecret +resources are deployed to the cluster, the Kube Seal operator decrypts the contents of the SealedSecret and generates a +Secret. + +In order for the encryption process to work, the SealedSecret content must be encrypted using at public certificate and +the Kube Seal process will decrypt the content using the matching private key that has been provided to the cluster as a +secret. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v14 + +### Terraform providers + +- tls provider + +## Module dependencies + +None + +## Example usage + +```hcl-terraform +module "cert" { + source = "github.com/cloud-native-toolkit/terraform-util-sealed-secret-cert.git" + + private_key_file = var.private_key_file + cert_file = var.cert_file +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/docs/util-clis.md b/2-standard/1-aro/200-openshift-gitops/docs/util-clis.md new file mode 100644 index 0000000..a30397d --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/docs/util-clis.md @@ -0,0 +1,45 @@ +# CLI module + +Module to download CLIs into local bin directory. This module is primarily intended to be used as a submodule within other modules. The CLIs currently supported are: + +- jq (jq) +- yq v3 and v4 (yq) +- igc (igc) +- kubeseal (kubeseal) +- gh cli (gh) +- glab cli (glab) +- rosa cli (rosa) +- kustomize cli (kustomize) +- ibmcloud cli (ibmcloud) +- ibmcloud infrastructure plugin (ibmcloud-is) +- ibmcloud observe plugin (ibmcloud-ob) +- ibmcloud kubernetes service plugin (ibmcloud-ks) +- ibmcloud container registry plugin (ibmcloud-cr) +- universal git client (gitu) +- OpenShift Installer (openshift-install-4.x[.y]) + + +The module outputs the bin directory for use by other modules. + +**Note:** This module uses an external data source to setup the clis. External data sources have a limitation in terms of real-time feedback of progress. To increase the visibility of what the module is doing, the data source writes logs to `clis-debug.log` in the current working directory. + +### Command-line tools + +- curl + +### Terraform providers + +None + +## Module dependencies + +None + +## Example usage + +```hcl-terraform +module "clis" { + source = "github.com/cloud-native-toolkit/terraform-util-clis.git" +} +``` + diff --git a/2-standard/1-aro/200-openshift-gitops/main.tf b/2-standard/1-aro/200-openshift-gitops/main.tf new file mode 100644 index 0000000..94704e7 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/main.tf @@ -0,0 +1,129 @@ +module "argocd-bootstrap" { + source = "github.com/cloud-native-toolkit/terraform-tools-argocd-bootstrap?ref=v1.12.0" + + bootstrap_path = module.gitops_repo.bootstrap_path + bootstrap_prefix = var.argocd-bootstrap_bootstrap_prefix + cluster_config_file = module.cluster.config_file_path + cluster_type = module.cluster.platform.type_code + create_webhook = var.argocd-bootstrap_create_webhook + git_token = module.gitops_repo.config_token + git_username = module.gitops_repo.config_username + gitops_repo_url = module.gitops_repo.config_repo_url + ingress_subdomain = module.cluster.platform.ingress + olm_namespace = module.olm.olm_namespace + operator_namespace = module.olm.target_namespace + sealed_secret_cert = module.sealed-secret-cert.cert + sealed_secret_private_key = module.sealed-secret-cert.private_key +} +module "cluster" { + source = "github.com/cloud-native-toolkit/terraform-ocp-login?ref=v1.6.0" + + ca_cert = var.cluster_ca_cert + ca_cert_file = var.cluster_ca_cert_file + cluster_version = var.cluster_cluster_version + ingress_subdomain = var.cluster_ingress_subdomain + login_password = var.cluster_login_password + login_token = var.cluster_login_token + login_user = var.cluster_login_user + server_url = var.server_url + skip = var.cluster_skip + tls_secret_name = var.cluster_tls_secret_name +} +module "config" { + source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config?ref=v1.1.1" + + banner_background_color = var.config_banner_background_color + banner_text = var.config_banner_text + banner_text_color = var.config_banner_text_color + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.toolkit_namespace.name + server_name = module.gitops_repo.server_name +} +module "gitea" { + source = "github.com/cloud-native-toolkit/terraform-tools-gitea?ref=v0.5.0" + + ca_cert = module.cluster.ca_cert + ca_cert_file = var.gitea_ca_cert_file + cluster_config_file = module.cluster.config_file_path + cluster_type = module.cluster.platform.type_code + instance_name = var.gitea_instance_name + instance_namespace = module.gitea_namespace.name + olm_namespace = module.olm.olm_namespace + operator_namespace = module.olm.target_namespace + password = var.gitea_password + username = var.gitea_username +} +module "gitea_namespace" { + source = "github.com/cloud-native-toolkit/terraform-k8s-namespace?ref=v3.2.3" + + cluster_config_file_path = module.cluster.config_file_path + create_operator_group = var.gitea_namespace_create_operator_group + name = var.gitea_namespace_name +} +module "gitops_repo" { + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.22.1" + + branch = var.gitops_repo_branch + debug = var.debug + gitea_host = module.gitea.host + gitea_org = module.gitea.org + gitea_token = module.gitea.token + gitea_username = module.gitea.username + gitops_namespace = var.gitops_repo_gitops_namespace + host = var.gitops_repo_host + org = var.gitops_repo_org + project = var.gitops_repo_project + public = var.gitops_repo_public + repo = var.gitops_repo_repo + sealed_secrets_cert = module.sealed-secret-cert.cert + server_name = var.gitops_repo_server_name + strict = var.gitops_repo_strict + token = var.gitops_repo_token + type = var.gitops_repo_type + username = var.gitops_repo_username +} +module "gitops-console-link-job" { + source = "github.com/cloud-native-toolkit/terraform-gitops-console-link-job?ref=v1.5.1" + + cluster_ingress_hostname = var.gitops-console-link-job_cluster_ingress_hostname + cluster_type = var.gitops-console-link-job_cluster_type + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.toolkit_namespace.name + server_name = module.gitops_repo.server_name + tls_secret_name = var.gitops-console-link-job_tls_secret_name +} +module "olm" { + source = "github.com/cloud-native-toolkit/terraform-k8s-olm?ref=v1.3.2" + + cluster_config_file = module.cluster.config_file_path + cluster_type = module.cluster.platform.type_code + cluster_version = module.cluster.platform.version +} +module "sealed-secret-cert" { + source = "github.com/cloud-native-toolkit/terraform-util-sealed-secret-cert?ref=v1.0.1" + + cert = var.sealed-secret-cert_cert + cert_file = var.sealed-secret-cert_cert_file + private_key = var.sealed-secret-cert_private_key + private_key_file = var.sealed-secret-cert_private_key_file +} +module "toolkit_namespace" { + source = "github.com/cloud-native-toolkit/terraform-gitops-namespace?ref=v1.12.2" + + argocd_namespace = var.toolkit_namespace_argocd_namespace + ci = var.toolkit_namespace_ci + create_operator_group = var.toolkit_namespace_create_operator_group + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + name = var.toolkit_namespace_name + server_name = module.gitops_repo.server_name +} +module "util-clis" { + source = "cloud-native-toolkit/clis/util" + version = "1.17.2" + + bin_dir = var.util-clis_bin_dir + clis = var.util-clis_clis == null ? null : jsondecode(var.util-clis_clis) +} diff --git a/2-standard/1-aro/200-openshift-gitops/outputs.tf b/2-standard/1-aro/200-openshift-gitops/outputs.tf new file mode 100644 index 0000000..eba03b0 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/outputs.tf @@ -0,0 +1,19 @@ +output "gitops_host" { + value = module.gitops_repo.config_host +} +output "gitops_org" { + value = module.gitops_repo.config_org +} +output "gitops_name" { + value = module.gitops_repo.config_name +} +output "gitops_project" { + value = module.gitops_repo.config_project +} +output "gitops_username" { + value = module.gitops_repo.config_username +} +output "gitops_token" { + value = module.gitops_repo.config_token + sensitive = true +} \ No newline at end of file diff --git a/2-standard/1-aro/200-openshift-gitops/providers.tf b/2-standard/1-aro/200-openshift-gitops/providers.tf new file mode 100644 index 0000000..459ee95 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/providers.tf @@ -0,0 +1,6 @@ + +provider "gitops" { + + + bin_dir = module.util-clis.bin_dir +} \ No newline at end of file diff --git a/2-standard/1-aro/200-openshift-gitops/terragrunt.hcl b/2-standard/1-aro/200-openshift-gitops/terragrunt.hcl new file mode 100644 index 0000000..37b9876 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/terragrunt.hcl @@ -0,0 +1,41 @@ +include "root" { + path = find_in_parent_folders() +} + +locals { + dependencies = yamldecode(file("${get_parent_terragrunt_dir()}/layers.yaml")) + + dep_105 = local.dependencies.names_105 + mock_105 = local.dependencies.mock_105 + cluster_config_path = fileexists("${get_parent_terragrunt_dir()}/${local.dep_105}/terragrunt.hcl") ? "${get_parent_terragrunt_dir()}/${local.dep_105}" : "${get_parent_terragrunt_dir()}/.mocks/${local.mock_105}" + +} + +// Reduce parallelism further for this layer +terraform { + extra_arguments "reduced_parallelism" { + commands = get_terraform_commands_that_need_parallelism() + arguments = ["-parallelism=2"] + } +} + +dependency "aro" { + config_path = local.cluster_config_path + skip_outputs = false + + mock_outputs_allowed_terraform_commands = ["init","validate","plan"] + mock_outputs = { + server_url = "https://fake.url.org:6443" + username = "fakeuser" + password = "fakepassword" + token = "faketoken" + } +} + +inputs = { + server_url = dependency.aro.outputs.cluster_serverURL + cluster_login_user = dependency.aro.outputs.cluster_username + cluster_login_password = dependency.aro.outputs.cluster_password + cluster_login_token= dependency.aro.outputs.cluster_token +} + diff --git a/2-standard/1-aro/200-openshift-gitops/variables.tf b/2-standard/1-aro/200-openshift-gitops/variables.tf new file mode 100644 index 0000000..835717f --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/variables.tf @@ -0,0 +1,231 @@ +variable "config_banner_background_color" { + type = string + description = "The background color of the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000)." + default = "purple" +} +variable "config_banner_text_color" { + type = string + description = "The text color for the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000)." + default = "white" +} +variable "config_banner_text" { + type = string + description = "The text that will appear in the top banner in the cluster" +} +variable "server_url" { + type = string + description = "The url for the OpenShift api" +} +variable "cluster_login_user" { + type = string + description = "Username for login" + default = "" +} +variable "cluster_login_password" { + type = string + description = "Password for login" + default = "" +} +variable "cluster_login_token" { + type = string + description = "Token used for authentication" +} +variable "cluster_skip" { + type = bool + description = "Flag indicating that the cluster login has already been performed" + default = false +} +variable "cluster_cluster_version" { + type = string + description = "[Deprecated] The version of the cluster (passed through to the output)" + default = "" +} +variable "cluster_ingress_subdomain" { + type = string + description = "[Deprecated] The ingress subdomain of the cluster (passed through to the output)" + default = "" +} +variable "cluster_tls_secret_name" { + type = string + description = "[Deprecated] The name of the secret containing the tls certificates for the ingress subdomain (passed through to the output)" + default = "" +} +variable "cluster_ca_cert" { + type = string + description = "The base64 encoded ca certificate" + default = "" +} +variable "cluster_ca_cert_file" { + type = string + description = "The path to the file that contains the ca certificate" + default = "" +} +variable "gitea_namespace_name" { + type = string + description = "The namespace that should be created" + default = "gitea" +} +variable "gitea_namespace_create_operator_group" { + type = bool + description = "Flag indicating that an operator group should be created in the namespace" + default = true +} +variable "gitea_instance_name" { + type = string + description = "The name for the instance" + default = "gitea" +} +variable "gitea_username" { + type = string + description = "The username for the instance" + default = "gitea-admin" +} +variable "gitea_password" { + type = string + description = "The password for the instance" + default = "" +} +variable "gitea_ca_cert_file" { + type = string + description = "The path to the file that contains the ca certificate" + default = "" +} +variable "gitops_repo_host" { + type = string + description = "The host for the git repository. The git host used can be a GitHub, GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If the host is null assumes in-cluster Gitea instance will be used." + default = "" +} +variable "gitops_repo_type" { + type = string + description = "[Deprecated] The type of the hosted git repository." + default = "" +} +variable "gitops_repo_org" { + type = string + description = "The org/group where the git repository exists/will be provisioned. If the value is left blank then the username org will be used." + default = "" +} +variable "gitops_repo_project" { + type = string + description = "The project that will be used for the git repo. (Primarily used for Azure DevOps repos)" + default = "" +} +variable "gitops_repo_username" { + type = string + description = "The username of the user with access to the repository" + default = "" +} +variable "gitops_repo_token" { + type = string + description = "The personal access token used to access the repository" + default = "" +} +variable "gitops_repo_repo" { + type = string + description = "The short name of the repository (i.e. the part after the org/group name)" +} +variable "gitops_repo_branch" { + type = string + description = "The name of the branch that will be used. If the repo already exists (provision=false) then it is assumed this branch already exists as well" + default = "main" +} +variable "gitops_repo_public" { + type = bool + description = "Flag indicating that the repo should be public or private" + default = false +} +variable "gitops_repo_gitops_namespace" { + type = string + description = "The namespace where ArgoCD is running in the cluster" + default = "openshift-gitops" +} +variable "gitops_repo_server_name" { + type = string + description = "The name of the cluster that will be configured via gitops. This is used to separate the config by cluster" + default = "default" +} +variable "gitops_repo_strict" { + type = bool + description = "Flag indicating that an error should be thrown if the repo already exists" + default = false +} +variable "debug" { + type = bool + description = "Flag indicating that debug loggging should be enabled" + default = false +} +variable "argocd-bootstrap_bootstrap_prefix" { + type = string + description = "The prefix used in ArgoCD to bootstrap the application" + default = "" +} +variable "argocd-bootstrap_create_webhook" { + type = bool + description = "Flag indicating that a webhook should be created in the gitops repo to notify argocd of changes" + default = true +} +variable "gitops-console-link-job_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the IKS cluster." + default = "" +} +variable "gitops-console-link-job_cluster_type" { + type = string + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" +} +variable "gitops-console-link-job_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "toolkit_namespace_name" { + type = string + description = "The value that should be used for the namespace" + default = "toolkit" +} +variable "toolkit_namespace_ci" { + type = bool + description = "Flag indicating that this namespace will be used for development (e.g. configmaps and secrets)" + default = false +} +variable "toolkit_namespace_create_operator_group" { + type = bool + description = "Flag indicating that an operator group should be created in the namespace" + default = true +} +variable "toolkit_namespace_argocd_namespace" { + type = string + description = "The namespace where argocd has been deployed" + default = "openshift-gitops" +} +variable "util-clis_bin_dir" { + type = string + description = "The directory where the clis should be downloaded. If not provided will default to ./bin" + default = "" +} +variable "util-clis_clis" { + type = string + description = "The list of clis that should be made available in the bin directory. Supported values are yq, jq, igc, helm, argocd, rosa, gh, glab, and kubeseal. (If not provided the list will default to yq, jq, and igc)" + default = "[\"yq\",\"jq\",\"igc\"]" +} +variable "sealed-secret-cert_cert" { + type = string + description = "The public key that will be used to encrypt sealed secrets. If not provided, a new one will be generated" + default = "" +} +variable "sealed-secret-cert_private_key" { + type = string + description = "The private key that will be used to decrypt sealed secrets. If not provided, a new one will be generated" + default = "" +} +variable "sealed-secret-cert_cert_file" { + type = string + description = "The file containing the public key that will be used to encrypt the sealed secrets. If not provided a new public key will be generated" + default = "" +} +variable "sealed-secret-cert_private_key_file" { + type = string + description = "The file containin the private key that will be used to encrypt the sealed secrets. If not provided a new private key will be generated" + default = "" +} diff --git a/2-standard/1-aro/200-openshift-gitops/version.tf b/2-standard/1-aro/200-openshift-gitops/version.tf new file mode 100644 index 0000000..5034007 --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/version.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + gitops = { + source = "cloud-native-toolkit/gitops" + } + + } +} \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-default-storage/bom.yaml b/2-standard/1-aro/210-azure-default-storage/bom.yaml new file mode 100644 index 0000000..e69de29 diff --git a/2-standard/1-aro/210-azure-default-storage/main.tf b/2-standard/1-aro/210-azure-default-storage/main.tf new file mode 100644 index 0000000..4197dd3 --- /dev/null +++ b/2-standard/1-aro/210-azure-default-storage/main.tf @@ -0,0 +1,3 @@ +output "default-storage" { + value = "Using default Azure storage" +} \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-default-storage/terragrunt.hcl b/2-standard/1-aro/210-azure-default-storage/terragrunt.hcl new file mode 100644 index 0000000..90156cf --- /dev/null +++ b/2-standard/1-aro/210-azure-default-storage/terragrunt.hcl @@ -0,0 +1,15 @@ +include "root" { + path = find_in_parent_folders() +} + +locals { + dependencies = yamldecode(file("${get_parent_terragrunt_dir()}/layers.yaml")) + + dep_105 = local.dependencies.names_105 + mock_105 = local.dependencies.mock_105 + cluster_config_path = fileexists("${get_parent_terragrunt_dir()}/${local.dep_105}/terragrunt.hcl") ? "${get_parent_terragrunt_dir()}/${local.dep_105}" : "${get_parent_terragrunt_dir()}/.mocks/${local.mock_105}" +} + +dependencies { + paths = ["${local.cluster_config_path}"] +} \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-portworx-storage/210-azure-portworx-storage.auto.tfvars b/2-standard/1-aro/210-azure-portworx-storage/210-azure-portworx-storage.auto.tfvars new file mode 100644 index 0000000..e121c45 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/210-azure-portworx-storage.auto.tfvars @@ -0,0 +1,27 @@ +## azure_subscription_id: The subscription id of the Azure account where the OpenShift cluster has been provisioned +#azure_subscription_id="" + +## azure_tenant_id: The tenant id of the Azure account where the OpenShift cluster has been provisioned +#azure_tenant_id="" + +## azure_client_id: The client id used to access the Azure account +#azure_client_id="" + +## azure_client_secret: The client secret used to access the Azure account +#azure_client_secret="" + +## portworx_spec_file: The path to the file that contains the yaml spec for the Portworx config. Either the `portworx_spec_file` or `portworx_spec` must be provided. The instructions for creating this configuration can be found at https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md +#portworx_spec_file="" + +## portworx_spec: The yaml spec for the Portworx config. Either the `portworx_spec_file` or `portworx_spec` must be provided. The instructions for creating this configuration can be found at https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md +#portworx_spec="" + +## azure-portworx_enable_encryption: Flag indicating portworx volumes should be encrypted +#azure-portworx_enable_encryption="" + +## server_url: The url for the OpenShift api +#server_url="" + +## cluster_login_token: Token used for authentication +#cluster_login_token="" + diff --git a/2-standard/1-aro/210-azure-portworx-storage/apply.sh b/2-standard/1-aro/210-azure-portworx-storage/apply.sh new file mode 100755 index 0000000..e64c76a --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/apply.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +VARIABLES_FILE="${1}" +if [[ -z "${VARIABLES_FILE}" ]]; then + VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" +fi + +YQ=$(command -v yq4 || command -v yq) +if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g") == "3" ]]; then + echo "yq v4 is required" + exit 1 +fi + +if [[ -f "${SCRIPT_DIR}/terraform/terraform.tfvars" ]]; then + cp "${SCRIPT_DIR}/terraform/terraform.tfvars" "${SCRIPT_DIR}/terraform/terraform.tfvars.backup" + rm "${SCRIPT_DIR}/terraform/terraform.tfvars" +fi + +if [[ ! -f "${VARIABLES_FILE}" ]]; then + echo "Variables can be provided in a yaml file passed as the first argument" + echo "" +fi + +TMP_VARIABLES_FILE="${VARIABLES_FILE}.tmp" + +echo "variables: []" > ${TMP_VARIABLES_FILE} + +cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while read name; do + default_value=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .defaultValue // ""' -) + sensitive=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .sensitive // false' -) + description=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .description // ""' -) + + variable_name="TF_VAR_${name}" + + environment_variable=$(env | grep "${variable_name}" | sed -E 's/.*=(.*).*/\1/g') + value="${environment_variable}" + if [[ -f "${VARIABLES_FILE}" ]]; then + value=$(cat "${VARIABLES_FILE}" | NAME="${name}" ${YQ} e '.variables[] | select(.name == env(NAME)) | .value // ""' -) + if [[ -z "${value}" ]]; then + value="${environment_variable}" + fi + fi + + while [[ -z "${value}" ]]; do + echo "Provide a value for '${name}':" + if [[ -n "${description}" ]]; then + echo " ${description}" + fi + sensitive_flag="" + if [[ "${sensitive}" == "true" ]]; then + sensitive_flag="-s" + fi + default_prompt="" + if [[ -n "${default_value}" ]]; then + default_prompt="(${default_value}) " + fi + read -u 1 ${sensitive_flag} -p "> ${default_prompt}" value + value=${value:-$default_value} + done + + echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + if [[ "${sensitive}" != "true" ]]; then + NAME="${name}" VALUE="${value}" ${YQ} e -i -P '.variables += [{"name": env(NAME), "value": env(VALUE)}]' "${TMP_VARIABLES_FILE}" + fi +done + +cp "${TMP_VARIABLES_FILE}" "${VARIABLES_FILE}" +rm "${TMP_VARIABLES_FILE}" + +cd ${SCRIPT_DIR}/terraform +terraform init +terraform apply diff --git a/2-standard/1-aro/210-azure-portworx-storage/bom.yaml b/2-standard/1-aro/210-azure-portworx-storage/bom.yaml new file mode 100644 index 0000000..dcfa787 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/bom.yaml @@ -0,0 +1,83 @@ +apiVersion: cloud.ibm.com/v1alpha1 +kind: BillOfMaterial +metadata: + name: 210-azure-portworx-storage + labels: + type: software + code: '210' + platform: azure + storage: portworx + annotations: + displayName: Azure - Portworx Cluster Storage + description: Installs Portworx into an OCP cluster on Azure +spec: + modules: + - name: azure-portworx + alias: azure-portworx + version: v1.0.2 + variables: + - name: region + scope: global + - name: name_prefix + scope: global + - name: client_id + scope: global + - name: client_secret + scope: global + - name: subscription_id + scope: global + - name: tenant_id + scope: global + - name: portworx_spec_file + scope: global + important: true + - name: portworx_spec + scope: global + - name: ocp-login + alias: cluster + version: v1.6.0 + variables: + - name: azure_subscription_id + type: string + description: >- + The subscription id of the Azure account where the OpenShift cluster has + been provisioned + - name: azure_tenant_id + type: string + description: >- + The tenant id of the Azure account where the OpenShift cluster has been + provisioned + - name: azure_client_id + type: string + description: The client id used to access the Azure account + - name: azure_client_secret + type: string + description: The client secret used to access the Azure account + - name: portworx_spec_file + type: string + description: >- + The path to the file that contains the yaml spec for the Portworx + config. Either the `portworx_spec_file` or `portworx_spec` must be + provided. The instructions for creating this configuration can be found + at + https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md + defaultValue: '' + - name: portworx_spec + type: string + description: >- + The yaml spec for the Portworx config. Either the `portworx_spec_file` + or `portworx_spec` must be provided. The instructions for creating this + configuration can be found at + https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md + defaultValue: '' + - name: azure-portworx_enable_encryption + type: bool + description: Flag indicating portworx volumes should be encrypted + defaultValue: false + - name: server_url + type: string + description: The url for the OpenShift api + - name: cluster_login_token + type: string + description: Token used for authentication + sensitive: true diff --git a/2-standard/1-aro/210-azure-portworx-storage/dependencies.dot b/2-standard/1-aro/210-azure-portworx-storage/dependencies.dot new file mode 100644 index 0000000..2d35ebf --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/dependencies.dot @@ -0,0 +1,6 @@ +digraph { + rankdir="BT" + "azure-portworx (azure-portworx)" -> "cluster (ocp-login)" +"azure-portworx (azure-portworx)" +"cluster (ocp-login)" + } \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-portworx-storage/destroy.sh b/2-standard/1-aro/210-azure-portworx-storage/destroy.sh new file mode 100755 index 0000000..7c27549 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/destroy.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd "${SCRIPT_DIR}/terraform" +terraform init +terraform destroy -auto-approve diff --git a/2-standard/1-aro/210-azure-portworx-storage/docs/azure-portworx.md b/2-standard/1-aro/210-azure-portworx-storage/docs/azure-portworx.md new file mode 100644 index 0000000..baf060d --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/docs/azure-portworx.md @@ -0,0 +1,120 @@ +# azure-portworx + + +### Description + +Terraform module to install Portworx into an OCP/ARO/IPI cluster on Azure, compatible with modules from https://modules.cloudnativetoolkit.dev + +### Prerequisites + +This module has 2 manual steps that must be completed before successful deployment: + +1. Azure service principal/credentials +2. Portworx configuration + +#### Azure service principal/credentials + +The provided `scripts/portworx-prereq.sh` script will collect/create the necessary service principle. The script required the resource group name, cluster name, and cluster type as input. Optionally the subscription id can be provided. If not provided, the subscription id will be looked up. + +1. Log into your Azure account using the `az` cli. +2. Run the `scripts/portworx-prereq.sh` script. + + ```shell + ./scripts/portworx-prereq.sh -t aro -g rg-name -n cluster-name + ``` + +3. If successful, the output of the script will look like the following. The output values can be provided as input to the automation. + + ```json + { + "azure_client_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "azure_client_secret": "XXXXXXX", + "azure_tenant_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "azure_subscription_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + } + ``` + +Alternatively, you can use known credentials for an existing service principal to allow Portworx to provision volumes for the cluster. + +##### Service principle details + +A service principal (service account) is used by the Portworx deployment to provision storage volumes that will be leveraged by Portworx once deployed into the OpenShift cluster. There are some specifics for service principals when deploying portworx, as detailed below: + +- **ARO Clusters:** - For ARO clusters, you must use the service principal that was created in the background when the ARO cluster was created. +- **IPI Clusters:** - For IPI clusters, you must create a service principal that has the following permissions: + + - `Microsoft.ContainerService/managedClusters/agentPools/read` + - `Microsoft.Compute/disks/delete` + - `Microsoft.Compute/disks/write` + - `Microsoft.Compute/disks/read` + - `Microsoft.Compute/virtualMachines/write` + - `Microsoft.Compute/virtualMachines/read` + - `Microsoft.Compute/virtualMachineScaleSets/virtualMachines/write` + - `Microsoft.Compute/virtualMachineScaleSets/virtualMachines/read` + +Before attempting to deploy this module, you can log into the `az` cli, and manually run the `scripts/portworx-prereq.sh` script, which will handle both of these cases. This script will output the credentials that are required to successfully deploy Portworx into the cluster. The output will be a JSON structure like: + + +#### Portworx configuration + +This module requires a Portworx configuration. Portworx is available in 2 flavors: `Enterprise` and `Essentials`. + +*Portworx Essentials* is free forever, but only supports a maximum of 5 nodes on a cluster, 200 volumes, and 5TB of storage. +*Portworx Enterprise* requires a subscription (has 30 day free trial), supports over 1000 nodes per cluster, and has unlimited storage. + +More detailed comparisons are available at: https://portworx.com/products/features/ + +Instructions for obtaining your portworx configuration are available at [portworx config](./PORTWORX_CONFIG.md) + +You can see an example in the [Example usage](#example-usage) section below. + +### Software dependencies + +The module depends on the following software components: + +#### Command-line tools + +- terraform >= v0.15 + +#### Terraform providers + +- nil + +### Module dependencies + +This module makes use of the output from other modules: + +- github.com/cloud-native-toolkit/terraform-ocp-login.git + - provides the `cluster_config_file` variable for the `azure-portworx` module. + +### Example usage + +Note: `osb_endpoint` and `user_id` are only required in `portworx_config` if `type` is `essentials`. These values are not required for type `enterprise`. + +```hcl-terraform +module "cluster-login" { + source = "github.com/cloud-native-toolkit/terraform-ocp-login.git" + + server_url = var.server_url + login_user = var.cluster_username + login_password = var.cluster_password + login_token = "" + ca_cert = var.ca_cert +} + +module "azure-portworx" { + source = "./module" + + azure_client_id = var.azure_client_id + azure_client_secret = var.azure_client_secret + azure_subscription_id = var.azure_subscription_id + azure_tenant_id = var.azure_tenant_id + cluster_config_file = module.terraform-ocp-login.platform.kubeconfig + cluster_type = "IPI" + portworx_spec_file = "${path.module}/px_spec.yaml" +} +``` + +## Acknowledgements +This module is a derivative of https://github.com/ibm-hcbt/terraform-ibm-cloud-pak/tree/main/modules/portworx_aws + diff --git a/2-standard/1-aro/210-azure-portworx-storage/docs/ocp-login.md b/2-standard/1-aro/210-azure-portworx-storage/docs/ocp-login.md new file mode 100644 index 0000000..6e4ad22 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/docs/ocp-login.md @@ -0,0 +1,36 @@ +# OCP Login + +Terraform module to log into a cluster and write the credentials into the kube config file. The file path is output by the module. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v0.15 + +### Terraform providers + +None + +## Module dependencies + +None + +## Example usage + +```hcl-terraform +module "dev_tools_argocd" { + source = "github.com/ibm-garage-cloud/terraform-tools-argocd.git?ref=v1.0.0" + + cluster_config_file = module.dev_cluster.config_file_path + cluster_type = module.dev_cluster.type + app_namespace = module.dev_cluster_namespaces.tools_namespace_name + ingress_subdomain = module.dev_cluster.ingress_hostname + olm_namespace = module.dev_software_olm.olm_namespace + operator_namespace = module.dev_software_olm.target_namespace + name = "argocd" +} +``` + diff --git a/2-standard/1-aro/210-azure-portworx-storage/main.tf b/2-standard/1-aro/210-azure-portworx-storage/main.tf new file mode 100644 index 0000000..fb7753f --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/main.tf @@ -0,0 +1,32 @@ +module "azure-portworx" { + source = "github.com/cloud-native-toolkit/terraform-azure-portworx?ref=v1.0.2" + + azure_client_id = var.client_id + azure_client_secret = var.client_secret + azure_subscription_id = var.subscription_id + azure_tenant_id = var.tenant_id + cluster_config_file = module.cluster.config_file_path + cluster_type = var.azure-portworx_cluster_type + disk_size = var.azure-portworx_disk_size + enable_encryption = var.azure-portworx_enable_encryption + kvdb_disk_size = var.azure-portworx_kvdb_disk_size + portworx_spec = var.portworx_spec + portworx_spec_file = var.portworx_spec_file + provision = var.azure-portworx_provision + px_enable_csi = var.azure-portworx_px_enable_csi + px_enable_monitoring = var.azure-portworx_px_enable_monitoring +} +module "cluster" { + source = "github.com/cloud-native-toolkit/terraform-ocp-login?ref=v1.6.0" + + ca_cert = var.cluster_ca_cert + ca_cert_file = var.cluster_ca_cert_file + cluster_version = var.cluster_cluster_version + ingress_subdomain = var.cluster_ingress_subdomain + login_password = var.cluster_login_password + login_token = var.cluster_login_token + login_user = var.cluster_login_user + server_url = var.server_url + skip = var.cluster_skip + tls_secret_name = var.cluster_tls_secret_name +} diff --git a/2-standard/1-aro/210-azure-portworx-storage/providers.tf b/2-standard/1-aro/210-azure-portworx-storage/providers.tf new file mode 100644 index 0000000..e38fc4d --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/providers.tf @@ -0,0 +1,5 @@ + +provider "azure" { + + +} \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-portworx-storage/terragrunt.hcl b/2-standard/1-aro/210-azure-portworx-storage/terragrunt.hcl new file mode 100644 index 0000000..bdf75f4 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/terragrunt.hcl @@ -0,0 +1,32 @@ +include "root" { + path = find_in_parent_folders() +} + +locals { + px_spec = get_env("TF_VAR_portworx_spec") + dependencies = yamldecode(file("${get_parent_terragrunt_dir()}/layers.yaml")) + + dep_105 = local.dependencies.names_105 + mock_105 = local.dependencies.mock_105 + cluster_config_path = fileexists("${get_parent_terragrunt_dir()}/${local.dep_105}/terragrunt.hcl") ? "${get_parent_terragrunt_dir()}/${local.dep_105}" : "${get_parent_terragrunt_dir()}/.mocks/${local.mock_105}" +} + +dependency "aro" { + config_path = local.cluster_config_path + + mock_outputs_allowed_terraform_commands = ["init","validate","plan"] + mock_outputs = { + server_url = "https://fake.url.org:6443" + username = "fakeuser" + password = "fakepassword" + } +} + +inputs = { + server_url = dependency.aro.outputs.server_url + cluster_login_user = dependency.aro.outputs.username + cluster_login_password = dependency.aro.outputs.password + azure-portworx_portworx_spec = local.px_spec + azure-portworx_cluster_type = "ARO" + cluster_login_token= dependency.aro.outputs.token +} \ No newline at end of file diff --git a/2-standard/1-aro/210-azure-portworx-storage/variables.tf b/2-standard/1-aro/210-azure-portworx-storage/variables.tf new file mode 100644 index 0000000..8130d07 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/variables.tf @@ -0,0 +1,109 @@ +variable "azure-portworx_provision" { + type = string + description = "If set to true installs Portworx on the given cluster" + default = "true" +} +variable "subscription_id" { + type = string + description = "The subscription id of the Azure account where the OpenShift cluster has been provisioned" +} +variable "tenant_id" { + type = string + description = "The tenant id of the Azure account where the OpenShift cluster has been provisioned" +} +variable "client_id" { + type = string + description = "The client id used to access the Azure account" +} +variable "client_secret" { + type = string + description = "The client secret used to access the Azure account" +} +variable "azure-portworx_cluster_type" { + type = string + description = "Type of OCP cluster on Azure (ARO | IPI)" + default = "ARO" +} +variable "azure-portworx_disk_size" { + type = string + description = "Disk size for each Portworx volume" + default = "1000" +} +variable "azure-portworx_kvdb_disk_size" { + type = string + description = "the value of azure-portworx_kvdb_disk_size" + default = "150" +} +variable "azure-portworx_px_enable_monitoring" { + type = bool + description = "Enable monitoring on PX" + default = true +} +variable "azure-portworx_px_enable_csi" { + type = bool + description = "Enable CSI on PX" + default = true +} +variable "portworx_spec_file" { + type = string + description = "The path to the file that contains the yaml spec for the Portworx config. Either the `portworx_spec_file` or `portworx_spec` must be provided. The instructions for creating this configuration can be found at https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md" + default = "" +} +variable "portworx_spec" { + type = string + description = "The yaml spec for the Portworx config. Either the `portworx_spec_file` or `portworx_spec` must be provided. The instructions for creating this configuration can be found at https://github.com/cloud-native-toolkit/terraform-azure-portworx/blob/main/PORTWORX_CONFIG.md" + default = "" +} +variable "azure-portworx_enable_encryption" { + type = bool + description = "Flag indicating portworx volumes should be encrypted" + default = false +} +variable "server_url" { + type = string + description = "The url for the OpenShift api" +} +variable "cluster_login_user" { + type = string + description = "Username for login" + default = "" +} +variable "cluster_login_password" { + type = string + description = "Password for login" + default = "" +} +variable "cluster_login_token" { + type = string + description = "Token used for authentication" +} +variable "cluster_skip" { + type = bool + description = "Flag indicating that the cluster login has already been performed" + default = false +} +variable "cluster_cluster_version" { + type = string + description = "[Deprecated] The version of the cluster (passed through to the output)" + default = "" +} +variable "cluster_ingress_subdomain" { + type = string + description = "[Deprecated] The ingress subdomain of the cluster (passed through to the output)" + default = "" +} +variable "cluster_tls_secret_name" { + type = string + description = "[Deprecated] The name of the secret containing the tls certificates for the ingress subdomain (passed through to the output)" + default = "" +} +variable "cluster_ca_cert" { + type = string + description = "The base64 encoded ca certificate" + default = "" +} +variable "cluster_ca_cert_file" { + type = string + description = "The path to the file that contains the ca certificate" + default = "" +} diff --git a/2-standard/1-aro/210-azure-portworx-storage/version.tf b/2-standard/1-aro/210-azure-portworx-storage/version.tf new file mode 100644 index 0000000..a6ee4b9 --- /dev/null +++ b/2-standard/1-aro/210-azure-portworx-storage/version.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + azure = { + source = "hashicorp/azurerm" + } + + } +} \ No newline at end of file diff --git a/2-standard/1-aro/220-dev-tools/220-dev-tools.auto.tfvars b/2-standard/1-aro/220-dev-tools/220-dev-tools.auto.tfvars new file mode 100644 index 0000000..5a73fe4 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/220-dev-tools.auto.tfvars @@ -0,0 +1,18 @@ +## gitops_repo_host: The host for the git repository. The git host used can be a GitHub, GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If the host is null assumes in-cluster Gitea instance will be used. +#gitops_repo_host="" + +## gitops_repo_org: The org/group where the git repository exists/will be provisioned. If the value is left blank then the username org will be used. +#gitops_repo_org="" + +## gitops_repo_project: The project that will be used for the git repo. (Primarily used for Azure DevOps repos) +#gitops_repo_project="" + +## gitops_repo_username: The username of the user with access to the repository +#gitops_repo_username="" + +## gitops_repo_token: The personal access token used to access the repository +#gitops_repo_token="" + +## gitops_repo_repo: The short name of the repository (i.e. the part after the org/group name) +#gitops_repo_repo="" + diff --git a/2-standard/1-aro/220-dev-tools/apply.sh b/2-standard/1-aro/220-dev-tools/apply.sh new file mode 100755 index 0000000..e64c76a --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/apply.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +VARIABLES_FILE="${1}" +if [[ -z "${VARIABLES_FILE}" ]]; then + VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" +fi + +YQ=$(command -v yq4 || command -v yq) +if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g") == "3" ]]; then + echo "yq v4 is required" + exit 1 +fi + +if [[ -f "${SCRIPT_DIR}/terraform/terraform.tfvars" ]]; then + cp "${SCRIPT_DIR}/terraform/terraform.tfvars" "${SCRIPT_DIR}/terraform/terraform.tfvars.backup" + rm "${SCRIPT_DIR}/terraform/terraform.tfvars" +fi + +if [[ ! -f "${VARIABLES_FILE}" ]]; then + echo "Variables can be provided in a yaml file passed as the first argument" + echo "" +fi + +TMP_VARIABLES_FILE="${VARIABLES_FILE}.tmp" + +echo "variables: []" > ${TMP_VARIABLES_FILE} + +cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while read name; do + default_value=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .defaultValue // ""' -) + sensitive=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .sensitive // false' -) + description=$(cat "${SCRIPT_DIR}/bom.yaml" | NAME="${name}" ${YQ} e '.spec.variables[] | select(.name == env(NAME)) | .description // ""' -) + + variable_name="TF_VAR_${name}" + + environment_variable=$(env | grep "${variable_name}" | sed -E 's/.*=(.*).*/\1/g') + value="${environment_variable}" + if [[ -f "${VARIABLES_FILE}" ]]; then + value=$(cat "${VARIABLES_FILE}" | NAME="${name}" ${YQ} e '.variables[] | select(.name == env(NAME)) | .value // ""' -) + if [[ -z "${value}" ]]; then + value="${environment_variable}" + fi + fi + + while [[ -z "${value}" ]]; do + echo "Provide a value for '${name}':" + if [[ -n "${description}" ]]; then + echo " ${description}" + fi + sensitive_flag="" + if [[ "${sensitive}" == "true" ]]; then + sensitive_flag="-s" + fi + default_prompt="" + if [[ -n "${default_value}" ]]; then + default_prompt="(${default_value}) " + fi + read -u 1 ${sensitive_flag} -p "> ${default_prompt}" value + value=${value:-$default_value} + done + + echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + if [[ "${sensitive}" != "true" ]]; then + NAME="${name}" VALUE="${value}" ${YQ} e -i -P '.variables += [{"name": env(NAME), "value": env(VALUE)}]' "${TMP_VARIABLES_FILE}" + fi +done + +cp "${TMP_VARIABLES_FILE}" "${VARIABLES_FILE}" +rm "${TMP_VARIABLES_FILE}" + +cd ${SCRIPT_DIR}/terraform +terraform init +terraform apply diff --git a/2-standard/1-aro/220-dev-tools/bom.yaml b/2-standard/1-aro/220-dev-tools/bom.yaml new file mode 100644 index 0000000..3709901 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/bom.yaml @@ -0,0 +1,80 @@ +apiVersion: cloud.ibm.com/v1alpha1 +kind: BillOfMaterial +metadata: + name: 220-dev-tools + labels: + type: software + code: '220' + annotations: + displayName: OpenShift development tools + description: Provisions development tools in an OpenShift cluster + deployment-type/gitops: 'true' + vpn/required: 'true' +spec: + modules: + - name: gitops-artifactory + alias: gitops-artifactory + version: v1.3.0 + - name: gitops-dashboard + alias: gitops-dashboard + version: v1.7.0 + - name: gitops-namespace + alias: tools_namespace + version: v1.12.2 + default: true + variables: + - name: name + value: tools + - name: gitops-pact-broker + alias: gitops-pact-broker + version: v1.2.0 + - name: gitops-repo + alias: gitops_repo + version: v1.22.1 + - name: gitops-sonarqube + alias: gitops-sonarqube + version: v1.3.0 + - name: gitops-swagger-editor + alias: gitops-swagger-editor + version: v0.1.0 + - name: gitops-tekton-resources + alias: gitops-tekton-resources + version: v2.1.0 + - name: util-clis + version: v1.17.2 + - name: gitops-buildah-unprivileged + version: v1.1.1 + variables: + - name: gitops_repo_host + type: string + description: >- + The host for the git repository. The git host used can be a GitHub, + GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If + the host is null assumes in-cluster Gitea instance will be used. + defaultValue: '' + - name: gitops_repo_org + type: string + description: >- + The org/group where the git repository exists/will be provisioned. If + the value is left blank then the username org will be used. + defaultValue: '' + - name: gitops_repo_project + type: string + description: >- + The project that will be used for the git repo. (Primarily used for + Azure DevOps repos) + defaultValue: '' + - name: gitops_repo_username + type: string + description: The username of the user with access to the repository + defaultValue: '' + - name: gitops_repo_token + type: string + description: The personal access token used to access the repository + defaultValue: '' + sensitive: true + - name: gitops_repo_repo + type: string + description: >- + The short name of the repository (i.e. the part after the org/group + name) diff --git a/2-standard/1-aro/220-dev-tools/dependencies.dot b/2-standard/1-aro/220-dev-tools/dependencies.dot new file mode 100644 index 0000000..cec6bc4 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/dependencies.dot @@ -0,0 +1,29 @@ +digraph { + rankdir="BT" + "gitops-artifactory (gitops-artifactory)" -> "gitops_repo (gitops-repo)" +"gitops-artifactory (gitops-artifactory)" -> "tools_namespace (gitops-namespace)" +"gitops-artifactory (gitops-artifactory)" +"gitops_repo (gitops-repo)" +"tools_namespace (gitops-namespace)" -> "gitops_repo (gitops-repo)" +"tools_namespace (gitops-namespace)" +"gitops-dashboard (gitops-dashboard)" -> "gitops_repo (gitops-repo)" +"gitops-dashboard (gitops-dashboard)" -> "tools_namespace (gitops-namespace)" +"gitops-dashboard (gitops-dashboard)" +"gitops-pact-broker (gitops-pact-broker)" -> "gitops_repo (gitops-repo)" +"gitops-pact-broker (gitops-pact-broker)" -> "tools_namespace (gitops-namespace)" +"gitops-pact-broker (gitops-pact-broker)" +"gitops-sonarqube (gitops-sonarqube)" -> "gitops_repo (gitops-repo)" +"gitops-sonarqube (gitops-sonarqube)" -> "tools_namespace (gitops-namespace)" +"gitops-sonarqube (gitops-sonarqube)" +"gitops-swagger-editor (gitops-swagger-editor)" -> "gitops_repo (gitops-repo)" +"gitops-swagger-editor (gitops-swagger-editor)" -> "tools_namespace (gitops-namespace)" +"gitops-swagger-editor (gitops-swagger-editor)" +"gitops-tekton-resources (gitops-tekton-resources)" -> "gitops_repo (gitops-repo)" +"gitops-tekton-resources (gitops-tekton-resources)" -> "tools_namespace (gitops-namespace)" +"gitops-tekton-resources (gitops-tekton-resources)" -> "gitops-buildah-unprivileged (gitops-buildah-unprivileged)" +"gitops-tekton-resources (gitops-tekton-resources)" +"gitops-buildah-unprivileged (gitops-buildah-unprivileged)" -> "gitops_repo (gitops-repo)" +"gitops-buildah-unprivileged (gitops-buildah-unprivileged)" -> "tools_namespace (gitops-namespace)" +"gitops-buildah-unprivileged (gitops-buildah-unprivileged)" +"util-clis (util-clis)" + } \ No newline at end of file diff --git a/2-standard/1-aro/220-dev-tools/destroy.sh b/2-standard/1-aro/220-dev-tools/destroy.sh new file mode 100755 index 0000000..7c27549 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/destroy.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd "${SCRIPT_DIR}/terraform" +terraform init +terraform destroy -auto-approve diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-artifactory.md b/2-standard/1-aro/220-dev-tools/docs/gitops-artifactory.md new file mode 100644 index 0000000..8b8776f --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-artifactory.md @@ -0,0 +1,39 @@ +# Artifactory Gitops module + +Module to populate a gitops repository with the resources to deploy Artifactory. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v0.15 +- git + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Cluster - github.com/ibm-garage-cloud/terraform-ibm-ocp-vpc.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + + +## Example usage + +```hcl-terraform +module "gitops_artifactory" { + source = "github.com/cloud-native-toolkit/terraform-gitops-artifactory.git" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + namespace = module.gitops_namespace.name + server_name = module.gitops.server_name +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-buildah-unprivileged.md b/2-standard/1-aro/220-dev-tools/docs/gitops-buildah-unprivileged.md new file mode 100644 index 0000000..ab550bf --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-buildah-unprivileged.md @@ -0,0 +1,36 @@ +# Buildah unprivileged gitops module + +Module to populate a gitops repo to set up a Red Hat OpenShift cluster to allow buildah to run unprivileged. (This is primarily necessary for IBM ROKS clusters.) + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 + +### Terraform providers + +None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + +## Example usage + +```hcl-terraform +module "buildah_unprivileged" { + source = "github.com/cloud-native-toolkit/terraform-gitops-buildah-unprivileged.git" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + server_name = module.gitops.server_name + namespace = module.gitops_namespace.name +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-dashboard.md b/2-standard/1-aro/220-dev-tools/docs/gitops-dashboard.md new file mode 100644 index 0000000..663b858 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-dashboard.md @@ -0,0 +1,42 @@ +# Developer Dashboard module + +Module that populates gitops repository with the Developer Dashboard chart from https://charts.cloudnativetoolkit.dev. Developer dashboard displays the links to all the tools installed on the cluster as part of CloudNative toolkit. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- kubectl + +### Terraform providers + +- IBM Cloud provider >= 1.5.3 +- Helm provider >= 1.1.1 (provided by Terraform) + +## Module dependencies + +This module makes use of the output from other modules: + +- Cluster - github.com/ibm-garage-cloud/terraform-ibm-container-platform.git +- Namespace - github.com/ibm-garage-clout/terraform-cluster-namespace.git +- etc + +## Example usage + +```hcl-terraform +module "dev_tools_argocd" { + source = "github.com/ibm-garage-cloud/terraform-tools-argocd.git?ref=v1.0.0" + + cluster_config_file = module.dev_cluster.config_file_path + cluster_type = module.dev_cluster.type + app_namespace = module.dev_cluster_namespaces.tools_namespace_name + ingress_subdomain = module.dev_cluster.ingress_hostname + olm_namespace = module.dev_software_olm.olm_namespace + operator_namespace = module.dev_software_olm.target_namespace + name = "argocd" +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-namespace.md b/2-standard/1-aro/220-dev-tools/docs/gitops-namespace.md new file mode 100644 index 0000000..374abd1 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-namespace.md @@ -0,0 +1,41 @@ +# Namespace gitops config + +Module to configure a GitOps repo to provision a namespace + + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- git + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps repo - github.com/cloud-native-toolkit/terraform-tools-gitops.git + +## Example usage + +```hcl-terraform +module "gitops_namespace" { + source = "github.com/ibm-garage-cloud/terraform-gitops-namespace.git" + + config_repo = module.gitops.config_repo + config_token = module.gitops.config_token + config_paths = module.gitops.config_paths + application_repo = module.gitops.application_repo + application_token = module.gitops.application_token + application_paths = module.gitops.application_paths + name = var.namespace + create_operator_group = false +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-pact-broker.md b/2-standard/1-aro/220-dev-tools/docs/gitops-pact-broker.md new file mode 100644 index 0000000..e4724f0 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-pact-broker.md @@ -0,0 +1,37 @@ +# Pact Broker gitops module + +Module to populate a gitops repo with the Pact Broker deployment. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- kubectl + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- Cluster - github.com/ibm-garage-cloud/terraform-ibm-container-platform.git +- Namespace - github.com/ibm-garage-clout/terraform-cluster-namespace.git +- etc +## Example usage + +```hcl-terraform +module "gitops_pactbroker" { + source = "github.com/cloud-native-toolkit/terraform-gitops-pactbroker.git" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + namespace = module.gitops_namespace.name + server_name = module.gitops.server_name +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-repo.md b/2-standard/1-aro/220-dev-tools/docs/gitops-repo.md new file mode 100644 index 0000000..37846fd --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-repo.md @@ -0,0 +1,56 @@ +# GitOps repo module + +Module that prepares a GitOps repo for use with ArgoCD. If the `provision` flag is `true` then a new git repo will be provisioned. If not, the provided repo name is expected to already exist. + +After cloning the git repo, an initial directory structure is set up along with bootstrap configuration to perform the initial setup of ArgoCD. + +## Supported git servers + +The module supports creating a repository in one of six different git servers: + +- GitHub +- GitHub Enterprise +- Gitlab +- Bitbucket +- Gitea +- Azure DevOps + +The selection of the git server type is determined by the value provided for the `host`. + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- git + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- None + +## Example usage + +```hcl-terraform +module "git" { + source = "github.com/cloud-native-toolkit/terraform-tools-gitops" + + host = var.git_host + org = var.git_org + repo = var.git_repo + username = var.git_username + token = var.git_token + project = var.git_project + gitops_namespace = var.gitops_namespace + sealed_secrets_cert = module.cert.cert + strict = var.gitops_strict +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-sonarqube.md b/2-standard/1-aro/220-dev-tools/docs/gitops-sonarqube.md new file mode 100644 index 0000000..58cd24c --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-sonarqube.md @@ -0,0 +1,42 @@ +# SonarQube gitops module + +Module to populate a gitops repo with the resources to deploy SonarQube + + + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 +- kubectl + +### Terraform providers + +- IBM Cloud provider >= 1.5.3 +- Helm provider >= 1.1.1 (provided by Terraform) + +## Module dependencies + +This module makes use of the output from other modules: + +- Cluster - github.com/ibm-garage-cloud/terraform-ibm-container-platform.git +- Namespace - github.com/ibm-garage-cloud/terraform-cluster-namespace.git +- etc. + +## Example usage + +```hcl-terraform +module "gitops_sonarqube" { + source = "https://github.com/cloud-native-toolkit/terraform-gitops-sonarqube" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + namespace = module.gitops_namespace.name + kubeseal_cert = module.gitops.sealed_secrets_cert + server_name = module.gitops.server_name +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-swagger-editor.md b/2-standard/1-aro/220-dev-tools/docs/gitops-swagger-editor.md new file mode 100644 index 0000000..25d1f35 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-swagger-editor.md @@ -0,0 +1,196 @@ +# Swagger Editor GitOps module +Module to populate a gitops repository with the resources required to provision Swagger Editor. +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform - v12 +- kubectl + +### Terraform providers + +- IBM Cloud provider >= 1.5.3 +- Helm provider >= 1.1.1 (provided by Terraform) + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git +- etc + +## Example usage + +```hcl-terraform +module "swagger_editor" { + source = "https://github.com/cloud-native-toolkit/terraform-gitops-swagger-editor.git" + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + server_name = module.gitops.server_name + namespace = module.gitops_namespace.name + kubeseal_cert = module.gitops.sealed_secrets_cert +} +``` + +## Anatomy of the GitOps module repository + +An automation modules is created from a template repository that includes a skeleton of the module logic and the automation framework to validate and release the module. + +### Module logic + +The module follows the naming convention of terraform modules: + +- **main.tf** - The logic for the module. The structure of the GitOps logic in the **main.tf** file is largely the same from GitOps module to the next with the difference being the yaml provided to populate the GitOps repo +- **variables.tf** - The input variables for the module. A number of modules are defined by default in the module and should remain. Additional variables can be added as needed by the module. +- **outputs.tf** - The output variables for the module. These are rarely used for GitOps modules but can provide values for downstream modules. +- **version.tf** - The minimum required terraform version. Currently, this is defaulted to `v0.15`. If any terraform providers are required by the module they would be added here as well, although this is highly unlikely for GitOps modules. +- **module.yaml** - The metadata descriptor for the module. Each of the automation modules provides a metadata file that describes the name, description, and external dependencies of the module. Metadata for the input variables can also be provided. When a release of the module is created, an automated workflow will supplement the contents of this file with the input and output variables defined in `variables.tf` and `outputs.tf` and publish the result to `index.yaml` on the `gh-pages` branch. +- **scripts/create-yaml.sh** - Script to set up the payload yaml for the GitOps repository in a temporary directory from which the repository will be populated. This script should be customized for the requirements of the module. +- **README.md** - The documentation for the module. An initial readme is provided with instructions at the top and a template for the module documentation at the bottom. + +### Module automation + +The automation modules rely heavily on [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) automatically validate changes to the module and release new versions. The GitHub Action workflows are found in **.github/workflows**. There are three workflows provided by default: + +#### Verify and release module (verify.yaml) + +This workflow runs for pull requests against the `main` branch and when changes are pushed to the `main` branch. + +```yaml +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +``` + +The `verify` job checks out the module and deploys the terraform template in the `test/stages` folder. (More on the details of this folder in a later section.) It applies the testcase(s) listed in the `strategy.matrix.testcase` variable against the terraform template to validate the module logic. It then runs the `.github/scripts/validate-deploy.sh` to verify that everything was deployed successfully. **Note:** This script should be customized to validate the resources provisioned by the module. After the deploy is completed, the destroy logic is also applied to validate the destroy logic and to clean up after the test. The parameters for the test case are defined in https://github.com/cloud-native-toolkit/action-module-verify/tree/main/env. New test cases can be added via pull request. + +The `verifyMetadata` job checks out the module and validates the module metadata against the module metadata schema to ensure the structure is valid. + +The `release` job creates a new release of the module. The job only runs if the `verify` and `verifyMetadata` jobs completed successfully AND if the workflow was started from a push to the `main` branch (i.e. not a change to a pull request). The job uses the **release-drafter/release-drafter** GitHub Action to create the release based on the configuration in `.github/release-drafter.yaml`. The configuration looks for labels on the pull request to determine the type of change for the release changelog (`enhancement`, `bug`, `chore`) and which portion of the version number to increment (`major`, `minor`, `patch`). + +#### Publish assets (publish-assets.yaml) + +This workflow runs when a new release is published (either manually or via an automated process). + +```yaml +on: + release: + types: + - published +``` + +When a release is created, the module is checked out and the metadata is built and validated. If the metadata is checks out then it is published to the `gh-pages` branch as `index.yaml` + +#### Notify (notify.yaml) + +This workflow runs when a new release is published (either manually or via an automated process). + +```yaml +on: + release: + types: + - published +``` + +When a release is created, a repository dispatch is sent out to the repositories listed in the `strategy.matrix.repo` variable. By default, the `automation-modules` and `ibm-garage-iteration-zero` repositories are notified. When those modules receive the notification, an automation workflow is triggered on their end to deal with the newly available module version. + +### Module metadata + +The module metadata adds extra descriptive information about the module that is used to build out the module catalog. + +```yaml +name: "" +type: gitops +description: "" +tags: + - tools + - gitops +versions: + - platforms: + - kubernetes + - ocp3 + - ocp4 + dependencies: + - id: gitops + refs: + - source: github.com/cloud-native-toolkit/terraform-tools-gitops.git + version: ">= 1.1.0" + - id: namespace + refs: + - source: github.com/cloud-native-toolkit/terraform-gitops-namespace.git + version: ">= 1.0.0" + variables: + - name: gitops_config + moduleRef: + id: gitops + output: gitops_config + - name: git_credentials + moduleRef: + id: gitops + output: git_credentials + - name: server_name + moduleRef: + id: gitops + output: server_name + - name: namespace + moduleRef: + id: namespace + output: name + - name: kubeseal_cert + moduleRef: + id: gitops + output: sealed_secrets_cert +``` + +- **name** - The `name` field is required and must be unique among the other modules. This value is used to reference the module in the Bill of Materials. +- **description** - The `description` should provide a summary of what the module does. +- **tags** - The `tags` are used to provide searchable keywords related to the module. +- **versions** - When the final module metadata is generated, the `versions` array will contain a different entry for each version with a snapshot of the inputs and outputs for that version. In the `module.yaml` file this array should contain a single entry that describes the current version's dependencies and inputs. +- **versions[*].platforms** - The target cluster types and versions supported by the module +- **versions[*].dependencies** - The external modules upon which this module depends. These dependencies are used to offload logic for which this module should not be responsible and retrieve the necessary values from the outputs of these dependencies. Additiaonlly, this allows resources to be shared between modules by referencing to the same external dependency instance. +- **versions[*].variables** - Additional metadata provided for the input variables. When the metadata is generated for the release, the information for all the input variables is read from `variables.tf` and is supplemented with the information provided here. If there is no additional information to add to a variable it can be excluded from `module.yaml`. Examples of variable metadata that can be added: mapping the variable to the output of a dependency or setting the scope of the variable to `global`, `ignore`, or `module` (the default). + +**Note:** For most all GitOps modules, the initial dependencies and variable mappings should be preserved. Additional dependencies and variable definitions can be added as needed. + +**Note:** As a design point, the gitops module should ideally not have a direct dependency on the cluster and should instead depend (exclusively) on the gitops repository. That way, the cluster itself might be inaccessible by the automation process but the software can still be installed in the cluster so long as the gitops repository is accessible. + +### Module test logic + +The `test/stages` folder contains the terraform template needed to execute the module. By convention, each module is defined in its own file. Also by convention, all prereqs or dependencies for the module are named `stage1-xxx` and the module to be tested is named `stage2-xxx`. The default test templates in the GitOps repo are set up to provision a GitOps repository, log into a cluster, provision ArgoCD in the cluster and bootstrap it with the GitOps repository, provision a namespace via GitOps where the module will be deployed then apply the module logic. The end result of this test terraform template should be a cluster that has been provisioned with the components of the module via the GitOps repository. + +This test logic will run every time a change is made to the repository to ensure there are no regressions to the module. + +## GitOps repository structure + +The GitOps modules assume the repository has been divided into three different layers to separate the different types of resources that will be provisioned in the cluster: + +1. `infrastucture` - the infrastructure layer contains cluster-wide and/or privileged resources like namespaces, rbac configuration, service accounts, and security context constraints. Most modules won't directly use this layer but may use submodules to configure service accounts and rbac that will be put in this layer. +2. `services` - the services layer contains shared middleware and software services that may be used by multiple applications deployed within the cluster. This includes things like databases, service mesh, api management software, or multi-tenanted development tools. Most components will be placed in this layer. +3. `application` - the application layer is where the gitops configuration to deploy applications that make use of the shared services is placed. Often this configuration will be applied to the GitOps repo as part of a CI/CD process to manage the application lifecycle. + +Within the layers, there are three different types that can be applied: + +1. `operator` - operator deployments are organized in a particular way in the gitops repository +2. `instances` - instances created from custom resources applied via an operator are organized in a different manner in the gitops repository +3. `base` - basically everything that is not an operator or operator instance deployment falls in this category + +In order to simplify the process of managing the gitops repository structure and the different configuration options, a command has been provided in the `igc` cli to populate the gitops repo - `igc gitops-module`. The layer and type are provided as arguments to the command as well as the directory where the yaml for the module is located and the details about the gitops repo. + +The yaml used to define the resources required to deploy the component can be defined as kustomize scripts, a helm chart, or as raw yaml in the directory. In most cases we use helm charts to simplify the required input configuration. + +## Development + +### Adding logic and updating the test + +1. Start by implementing the logic in `main.tf`, adding required variables to `variables.tf` as necessary. +2. Update the `test/stages/stage2-xxx.tf` file with any of the required variables. +3. If the module has dependencies on other modules, add them as `test/stages/stage1-xxx.tf` and reference the output variables as variable inputs. +4. Review the validation logic in `.github/scripts/validate-deploy.sh` and update as appropriate. +5. Push the changes to the remote branch and review the check(s) on the pull request. If the checks fail, review the log and make the necessary adjustments. + +For more details on development and contribution,refer to https://github.com/cloud-native-toolkit/automation-modules/tree/main/md diff --git a/2-standard/1-aro/220-dev-tools/docs/gitops-tekton-resources.md b/2-standard/1-aro/220-dev-tools/docs/gitops-tekton-resources.md new file mode 100644 index 0000000..519ca56 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/gitops-tekton-resources.md @@ -0,0 +1,35 @@ +# Tekton Resources GitOps module + +Module to populate a gitops repo with Tekton resources (tasks and pipelines). + +## Software dependencies + +The module depends on the following software components: + +### Command-line tools + +- terraform >= v0.15 + +### Terraform providers + +- None + +## Module dependencies + +This module makes use of the output from other modules: + +- GitOps repo - github.com/cloud-native-toolkit/terraform-tools-gitops.git +- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + +## Example usage + +```hcl-terraform +module "tekton_resources" { + source = "github.com/cloud-native-toolkit/terraform-gitops-tekton-resources" + + gitops_config = module.gitops.gitops_config + git_credentials = module.gitops.git_credentials + namespace = module.gitops_namespace.name +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/docs/util-clis.md b/2-standard/1-aro/220-dev-tools/docs/util-clis.md new file mode 100644 index 0000000..a30397d --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/docs/util-clis.md @@ -0,0 +1,45 @@ +# CLI module + +Module to download CLIs into local bin directory. This module is primarily intended to be used as a submodule within other modules. The CLIs currently supported are: + +- jq (jq) +- yq v3 and v4 (yq) +- igc (igc) +- kubeseal (kubeseal) +- gh cli (gh) +- glab cli (glab) +- rosa cli (rosa) +- kustomize cli (kustomize) +- ibmcloud cli (ibmcloud) +- ibmcloud infrastructure plugin (ibmcloud-is) +- ibmcloud observe plugin (ibmcloud-ob) +- ibmcloud kubernetes service plugin (ibmcloud-ks) +- ibmcloud container registry plugin (ibmcloud-cr) +- universal git client (gitu) +- OpenShift Installer (openshift-install-4.x[.y]) + + +The module outputs the bin directory for use by other modules. + +**Note:** This module uses an external data source to setup the clis. External data sources have a limitation in terms of real-time feedback of progress. To increase the visibility of what the module is doing, the data source writes logs to `clis-debug.log` in the current working directory. + +### Command-line tools + +- curl + +### Terraform providers + +None + +## Module dependencies + +None + +## Example usage + +```hcl-terraform +module "clis" { + source = "github.com/cloud-native-toolkit/terraform-util-clis.git" +} +``` + diff --git a/2-standard/1-aro/220-dev-tools/main.tf b/2-standard/1-aro/220-dev-tools/main.tf new file mode 100644 index 0000000..31eeed2 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/main.tf @@ -0,0 +1,124 @@ +module "gitops_repo" { + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.22.1" + + branch = var.gitops_repo_branch + debug = var.debug + gitea_host = var.gitops_repo_gitea_host + gitea_org = var.gitops_repo_gitea_org + gitea_token = var.gitops_repo_gitea_token + gitea_username = var.gitops_repo_gitea_username + gitops_namespace = var.gitops_repo_gitops_namespace + host = var.gitops_repo_host + org = var.gitops_repo_org + project = var.gitops_repo_project + public = var.gitops_repo_public + repo = var.gitops_repo_repo + sealed_secrets_cert = var.gitops_repo_sealed_secrets_cert + server_name = var.gitops_repo_server_name + strict = var.gitops_repo_strict + token = var.gitops_repo_token + type = var.gitops_repo_type + username = var.gitops_repo_username +} +module "gitops-artifactory" { + source = "github.com/cloud-native-toolkit/terraform-gitops-artifactory?ref=v1.3.0" + + cluster_ingress_hostname = var.gitops-artifactory_cluster_ingress_hostname + cluster_type = var.gitops-artifactory_cluster_type + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.tools_namespace.name + persistence = var.gitops-artifactory_persistence + server_name = module.gitops_repo.server_name + storage_class = var.gitops-artifactory_storage_class + tls_secret_name = var.gitops-artifactory_tls_secret_name +} +module "gitops-buildah-unprivileged" { + source = "github.com/cloud-native-toolkit/terraform-gitops-buildah-unprivileged?ref=v1.1.1" + + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.tools_namespace.name + server_name = module.gitops_repo.server_name +} +module "gitops-dashboard" { + source = "github.com/cloud-native-toolkit/terraform-gitops-dashboard?ref=v1.7.0" + + cluster_ingress_hostname = var.gitops-dashboard_cluster_ingress_hostname + cluster_type = var.gitops-dashboard_cluster_type + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + image_tag = var.gitops-dashboard_image_tag + namespace = module.tools_namespace.name + server_name = module.gitops_repo.server_name + tls_secret_name = var.gitops-dashboard_tls_secret_name +} +module "gitops-pact-broker" { + source = "github.com/cloud-native-toolkit/terraform-gitops-pact-broker?ref=v1.2.0" + + cluster_ingress_hostname = var.gitops-pact-broker_cluster_ingress_hostname + cluster_type = var.gitops-pact-broker_cluster_type + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.tools_namespace.name + server_name = module.gitops_repo.server_name + tls_secret_name = var.gitops-pact-broker_tls_secret_name +} +module "gitops-sonarqube" { + source = "github.com/cloud-native-toolkit/terraform-gitops-sonarqube?ref=v1.3.0" + + cluster_ingress_hostname = var.gitops-sonarqube_cluster_ingress_hostname + cluster_type = var.gitops-sonarqube_cluster_type + cluster_version = var.gitops-sonarqube_cluster_version + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + hostname = var.gitops-sonarqube_hostname + kubeseal_cert = module.gitops_repo.sealed_secrets_cert + namespace = module.tools_namespace.name + persistence = var.gitops-sonarqube_persistence + plugins = var.gitops-sonarqube_plugins == null ? null : jsondecode(var.gitops-sonarqube_plugins) + server_name = module.gitops_repo.server_name + service_account_name = var.gitops-sonarqube_service_account_name + storage_class = var.gitops-sonarqube_storage_class + tls_secret_name = var.gitops-sonarqube_tls_secret_name +} +module "gitops-swagger-editor" { + source = "github.com/cloud-native-toolkit/terraform-gitops-swagger-editor?ref=v0.1.0" + + cluster_ingress_hostname = var.gitops-swagger-editor_cluster_ingress_hostname + cluster_type = var.gitops-swagger-editor_cluster_type + enable_sso = var.gitops-swagger-editor_enable_sso + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + kubeseal_cert = module.gitops_repo.sealed_secrets_cert + namespace = module.tools_namespace.name + server_name = module.gitops_repo.server_name + tls_secret_name = var.gitops-swagger-editor_tls_secret_name +} +module "gitops-tekton-resources" { + source = "github.com/cloud-native-toolkit/terraform-gitops-tekton-resources?ref=v2.1.0" + + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.tools_namespace.name + server_name = module.gitops_repo.server_name + task_release = var.gitops-tekton-resources_task_release +} +module "tools_namespace" { + source = "github.com/cloud-native-toolkit/terraform-gitops-namespace?ref=v1.12.2" + + argocd_namespace = var.tools_namespace_argocd_namespace + ci = var.tools_namespace_ci + create_operator_group = var.tools_namespace_create_operator_group + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + name = var.tools_namespace_name + server_name = module.gitops_repo.server_name +} +module "util-clis" { + source = "cloud-native-toolkit/clis/util" + version = "1.17.2" + + bin_dir = var.util-clis_bin_dir + clis = var.util-clis_clis == null ? null : jsondecode(var.util-clis_clis) +} diff --git a/2-standard/1-aro/220-dev-tools/providers.tf b/2-standard/1-aro/220-dev-tools/providers.tf new file mode 100644 index 0000000..459ee95 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/providers.tf @@ -0,0 +1,6 @@ + +provider "gitops" { + + + bin_dir = module.util-clis.bin_dir +} \ No newline at end of file diff --git a/2-standard/1-aro/220-dev-tools/terragrunt.hcl b/2-standard/1-aro/220-dev-tools/terragrunt.hcl new file mode 100644 index 0000000..94ccef4 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/terragrunt.hcl @@ -0,0 +1,43 @@ +include "root" { + path = find_in_parent_folders() +} + +locals { + dependencies = yamldecode(file("${get_parent_terragrunt_dir()}/layers.yaml")) + + dep_200 = local.dependencies.names_200 + mock_200 = local.dependencies.mock_200 +} + +// Reduce parallelism further for this layer +terraform { + extra_arguments "reduced_parallelism" { + commands = get_terraform_commands_that_need_parallelism() + arguments = ["-parallelism=2"] + } +} + +dependency "gitops" { + config_path = fileexists("${get_parent_terragrunt_dir()}/${local.dep_200}/terragrunt.hcl") ? "${get_parent_terragrunt_dir()}/${local.dep_200}" : "${get_parent_terragrunt_dir()}/.mocks/${local.mock_200}" + skip_outputs = fileexists("${get_parent_terragrunt_dir()}/${local.dep_200}/terragrunt.hcl") ? false : true + # skip_outputs = true + + mock_outputs_allowed_terraform_commands = ["validate", "init", "plan", "destroy", "output"] + mock_outputs = { + gitops_host = "" + gitops_org = "" + gitops_name = "" + gitops_project = "" + gitops_username = "" + gitops_token = "" + } +} + +inputs = { + gitops_repo_host = dependency.gitops.outputs.gitops_host + gitops_repo_org = dependency.gitops.outputs.gitops_org + gitops_repo_repo = dependency.gitops.outputs.gitops_name + gitops_repo_project = dependency.gitops.outputs.gitops_project + gitops_repo_username = dependency.gitops.outputs.gitops_username + gitops_repo_token = dependency.gitops.outputs.gitops_token +} \ No newline at end of file diff --git a/2-standard/1-aro/220-dev-tools/variables.tf b/2-standard/1-aro/220-dev-tools/variables.tf new file mode 100644 index 0000000..5a863ab --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/variables.tf @@ -0,0 +1,249 @@ +variable "gitops-artifactory_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the IKS cluster." + default = "" +} +variable "gitops-artifactory_cluster_type" { + type = string + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" +} +variable "gitops-artifactory_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "gitops-artifactory_storage_class" { + type = string + description = "The storage class to use for the persistent volume claim" + default = "" +} +variable "gitops-artifactory_persistence" { + type = bool + description = "Flag to indicate if persistence should be enabled" + default = true +} +variable "gitops-dashboard_cluster_type" { + type = string + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "openshift" +} +variable "gitops-dashboard_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the IKS cluster." + default = "" +} +variable "gitops-dashboard_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "gitops-dashboard_image_tag" { + type = string + description = "The image version tag to use" + default = "v1.4.4" +} +variable "tools_namespace_name" { + type = string + description = "The value that should be used for the namespace" + default = "tools" +} +variable "tools_namespace_ci" { + type = bool + description = "Flag indicating that this namespace will be used for development (e.g. configmaps and secrets)" + default = false +} +variable "tools_namespace_create_operator_group" { + type = bool + description = "Flag indicating that an operator group should be created in the namespace" + default = true +} +variable "tools_namespace_argocd_namespace" { + type = string + description = "The namespace where argocd has been deployed" + default = "openshift-gitops" +} +variable "gitops-pact-broker_cluster_type" { + type = string + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" +} +variable "gitops-pact-broker_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the IKS cluster." + default = "" +} +variable "gitops-pact-broker_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "gitops_repo_host" { + type = string + description = "The host for the git repository. The git host used can be a GitHub, GitHub Enterprise, Gitlab, Bitbucket, Gitea or Azure DevOps server. If the host is null assumes in-cluster Gitea instance will be used." + default = "" +} +variable "gitops_repo_type" { + type = string + description = "[Deprecated] The type of the hosted git repository." + default = "" +} +variable "gitops_repo_org" { + type = string + description = "The org/group where the git repository exists/will be provisioned. If the value is left blank then the username org will be used." + default = "" +} +variable "gitops_repo_project" { + type = string + description = "The project that will be used for the git repo. (Primarily used for Azure DevOps repos)" + default = "" +} +variable "gitops_repo_username" { + type = string + description = "The username of the user with access to the repository" + default = "" +} +variable "gitops_repo_token" { + type = string + description = "The personal access token used to access the repository" + default = "" +} +variable "gitops_repo_gitea_host" { + type = string + description = "The host for the default gitea repository." + default = "" +} +variable "gitops_repo_gitea_org" { + type = string + description = "The org/group for the default gitea repository. If not provided, the value will default to the username org" + default = "" +} +variable "gitops_repo_gitea_username" { + type = string + description = "The username of the default gitea repository" + default = "" +} +variable "gitops_repo_gitea_token" { + type = string + description = "The personal access token used to access the repository" + default = "" +} +variable "gitops_repo_repo" { + type = string + description = "The short name of the repository (i.e. the part after the org/group name)" +} +variable "gitops_repo_branch" { + type = string + description = "The name of the branch that will be used. If the repo already exists (provision=false) then it is assumed this branch already exists as well" + default = "main" +} +variable "gitops_repo_public" { + type = bool + description = "Flag indicating that the repo should be public or private" + default = false +} +variable "gitops_repo_gitops_namespace" { + type = string + description = "The namespace where ArgoCD is running in the cluster" + default = "openshift-gitops" +} +variable "gitops_repo_server_name" { + type = string + description = "The name of the cluster that will be configured via gitops. This is used to separate the config by cluster" + default = "default" +} +variable "gitops_repo_sealed_secrets_cert" { + type = string + description = "The certificate/public key used to encrypt the sealed secrets" + default = "" +} +variable "gitops_repo_strict" { + type = bool + description = "Flag indicating that an error should be thrown if the repo already exists" + default = false +} +variable "debug" { + type = bool + description = "Flag indicating that debug loggging should be enabled" + default = false +} +variable "gitops-sonarqube_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the IKS cluster." + default = "" +} +variable "gitops-sonarqube_cluster_type" { + type = string + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" +} +variable "gitops-sonarqube_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "gitops-sonarqube_storage_class" { + type = string + description = "The storage class to use for the persistent volume claim" + default = "" +} +variable "gitops-sonarqube_service_account_name" { + type = string + description = "The name of the service account that should be used for the deployment" + default = "sonarqube-sonarqube" +} +variable "gitops-sonarqube_plugins" { + type = string + description = "The list of plugins that will be installed on SonarQube" + default = "[\"https://github.com/checkstyle/sonar-checkstyle/releases/download/4.33/checkstyle-sonar-plugin-4.33.jar\",\"https://github.com/AmadeusITGroup/sonar-stash/releases/download/1.6.0/sonar-stash-plugin-1.6.0.jar\"]" +} +variable "gitops-sonarqube_hostname" { + type = string + description = "The hostname that will be used for the ingress/route" + default = "sonarqube" +} +variable "gitops-sonarqube_persistence" { + type = bool + description = "Flag indicating that persistence should be enabled for the pods" + default = false +} +variable "gitops-sonarqube_cluster_version" { + type = string + description = "The cluster version" + default = "" +} +variable "gitops-swagger-editor_enable_sso" { + type = bool + description = "Flag indicating if oauth should be applied (only available for OpenShift)" + default = true +} +variable "gitops-swagger-editor_tls_secret_name" { + type = string + description = "The name of the secret containing the tls certificate values" + default = "" +} +variable "gitops-swagger-editor_cluster_ingress_hostname" { + type = string + description = "Ingress hostname of the cluster." + default = "" +} +variable "gitops-swagger-editor_cluster_type" { + type = string + description = "The cluster type (openshift or kubernetes)" + default = "openshift" +} +variable "gitops-tekton-resources_task_release" { + type = string + description = "The release version of the tekton tasks" + default = "v3.0.3" +} +variable "util-clis_bin_dir" { + type = string + description = "The directory where the clis should be downloaded. If not provided will default to ./bin" + default = "" +} +variable "util-clis_clis" { + type = string + description = "The list of clis that should be made available in the bin directory. Supported values are yq, jq, igc, helm, argocd, rosa, gh, glab, and kubeseal. (If not provided the list will default to yq, jq, and igc)" + default = "[\"yq\",\"jq\",\"igc\"]" +} diff --git a/2-standard/1-aro/220-dev-tools/version.tf b/2-standard/1-aro/220-dev-tools/version.tf new file mode 100644 index 0000000..5034007 --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/version.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + gitops = { + source = "cloud-native-toolkit/gitops" + } + + } +} \ No newline at end of file diff --git a/2-standard/1-aro/README.md b/2-standard/1-aro/README.md new file mode 100644 index 0000000..b89391c --- /dev/null +++ b/2-standard/1-aro/README.md @@ -0,0 +1,187 @@ +# Azure Quick Start Reference Architecture - Azure RedHat OpenShift (ARO) + +Automation to provision the Quick Start reference architecture on Azure. This architecture implements the minimum infrastructure required to stand up a managed Red Hat OpenShift cluster with public endpoints. + +## Reference Architecture + +![QuickStart](architecture.png) + +The automation is delivered in a number of layers that are applied in order. Layer (such as `200`) provisions the infrastructure including the Red Hat OpenShift cluster and the remaining layers provide configuration inside the cluster. Each layer depends on resources provided in the layer before it (e.g. `200` depends on `105`). Where two layers have the same numbers (e.g. `210`), you have a choice of which layer to apply. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Layer nameLayer descriptionProvided resources
105 - IBM VPC OpenShiftThis layer provisions the Azure infrastructure and OpenShift. It will create a new VNet and other networking components required to support the OpenShift cluster. An existing registered DNS zone for the required domain name is required (refer to prerequisites). +

Network

+
    +
  • Virtual network
  • +
  • VNet Master and Worker Subnets
  • +
  • Network Security Group
  • +
  • Inbound and outbound Load Balancer
  • +
  • Red Hat OpenShift cluster
  • +
+
200 - IBM OpenShift GitopsThis layer provisions OpenShift CI/CD tools into the cluster, a GitOps repository, and bootstraps the repository to the OpenShift Gitops instance. +

Software

+
    +
  • OpenShift GitOps (ArgoCD)
  • +
  • OpenShift Pipelines (Tekton)
  • +
  • Sealed Secrets (Kubeseal)
  • +
  • GitOps repo
  • +
+
210 - Azure StorageThe storage layer has two options - default or Portworx. The default option uses Azure's storage for OpenShift persistent volumes. For quickstart, this is Premium_LRS. Other options can be configured post implementation through the OpenShift console. The Portworx option implements either a Portworx Essentials or Portworx Enterprise deployment onto the OpenShift cluster. The type of Portworx deployment is determined by the supplied Portworx specification file. +

Default

+
    +
  • Azure storage class +
+

Portworx

+
    +
  • Portworx operator
  • +
  • Portworx storage classes
  • +
+
220 - Dev ToolsThe dev tools layer installs standard continuous integration (CI) pipelines that integrate with tools that support the software development lifecycle. +

Software

+
    +
  • Artifactory
  • +
  • Developer Dashboard
  • +
  • Pact Broker
  • +
  • Sonarqube
  • +
  • Tekton Resources
  • +
+
+ +## Automation + +### Prerequisites + +1. Access to an Azure account with "Owner" and "User Access Administrator" roles in an Azure Subscription. The user must be able to create a service principal per the below prerequisite. + +2. Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). + This is required to setup the service principal per the below instructions and to setup the ARO cluster. If using the container approach, the CLI is included in the cli-tools image. + +4. [Create a Service Principal](https://github.com/openshift/installer/blob/d0f7654bc4a0cf73392371962aef68cd9552b5dd/docs/user/azure/credentials.md) with proper IAM roles. + 1. Create the service principal account if it does not already exist: + ```shell + az ad sp create-for-rbac --role Contributor --name --scopes /subscriptions/$SUBSCRIPTION_ID + ``` + where SUBSCRIPTION_ID is the Azure subscription where the cluster is to be deployed and `service_principal_name` is the name to be assigned to the service principal. + Make a copy of the details provided + ```json + "addId":"", + "displayName":"", + "password":"", + "tenant":"" + ``` + + 1. Give permissions to the service principal to create other service principals and the ARO cluster (refer [here](./sp-setup.md) for details) + +5. Get your [OpenShift installer pull secret](https://console.redhat.com/openshift/install/pull-secret) and save it in `./pull-secret`. If a pull secret is not included, the ARO cluster will still be deployed, however, it will not have access to additional Red Hat features. + +6. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. + + ```shell + brew install docker colima + colima start + ``` + +### Setup + +1. Clone this repository to your local SRE laptop or into a secure terminal. Open a shell into the cloned directory. +2. Copy **credentials.template** to **credentials.properties**. + ```shell + cp credentials.template credentials.properties + ``` +3. Provide values for the variables in **credentials.properties** (**Note:** `*.properties` has been added to **.gitignore** to ensure that the file containing the apikey cannot be checked into Git.) + - **TF_VAR_subscription_id** - The Azure subscription id where the cluster will be deployed + - **TF_VAR_tenant_id** - The Azure tenant id that owns the subscription + - **TV_VAR_client_id** - The id of the service principal with Owner and User Administrator access to the subscription for cluster creation + - **TV_VAR_client_secret** - The password of the service principal with Owner and User Administrator access to the subscription for cluster creation + - **TV_VAR_pull_secret** - The contents of the Red Hat OpenShift pull secret downloaded in the prerequsite steps + - **TF_VAR_acme_registration_email** - (Optional) If using an auto-generated ingress certificate, this is the email address with which to register the certificate with LetsEncrypt. + - **TF_VAR_testing** - This value is used to determine whether testing or staging variables should be utilised. Lease as `none` for production deployments. A value other than `none` will request in a non-production deployment. + - **TF_VAR_portworx_spec** - A base64 encoded string of the Portworx specificatin yaml file. If left blank and using Portworx, ensure you specify the path to the Portworx specification yaml file in the `terraform.tfvars` file. For a Portworx implementation, either the `portworx_spec` or the `portworx_spec_file` values must be specified. If neither if specified, Portworx will not implement correctly. + - **TF_VAR_gitops_repo_username** - The username for the gitops repository (leave blank if using GiTea) + - **TF_VAR_gitops_repo_token** - The access token for the gitops repository (leave blank if using GiTea) + - **TF_VAR_gitops_repo_org** - The organisation for the gitops repository (leave blank if using a personal repository or using GiTea) + +4. Run **./launch.sh**. This will start a container image with the prompt opened in the `/terraform` directory, pointed to the repo directory. +5. Create a working copy of the terraform by running **./setup-workspace.sh**. The script makes a copy of the terraform in `/workspaces/current` and set up a "terraform.tfvars" file populated with default values. The script can be run interactively by just running **./setup-workspace.sh** or by providing command line parameters as specified below. + ``` + Usage: setup-workspace.sh [-f FLAVOR] [-s STORAGE] [-c CERT_TYPE] [-r REGION] [-n PREFIX_NAME] + + where: + - **FLAVOR** - the type of deployment `quickstart`, `standard` or `advanced`. If not provided, will default to quickstart. + - **STORAGE** - The storage provider. Possible options are `portworx` or `odf`. If not provided as an argument, a prompt will be shown. + - **CERT_TYPE** - The type of ingress certificate to apply. Possible options are `acme` or `byo`. Acme will obtain certificates from LetsEncrypt for the new cluster. BYO requires providing the paths to valid certificates in the **terraform.tfvars** file. + - **REGION** - the Azure location where the infrastructure will be provided ([available regions](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview)). Codes for each location can be obtained from the CLI using, + ```shell + az account list-locations -o table + ``` + If not provided the value defaults to `eastus` + - **PREFIX_NAME** - the name prefix that should be added to all the resources. If not provided a prefix will not be added. + ``` +6. Change the directory to the current workspace where the automation was configured (e.g. `/workspaces/current`). +7. Inspect **terraform.tfvars** to see if there are any variables that should be changed. (The **setup-workspace.sh** script has generated **terraform.tfvars** with default values. At a minimum, modify the ***base_domain_name*** and ***resource_group_name*** values to suit the Azure DNS zone configured in the prerequisite steps. ) + - **base_domain_name** - the full subdomain delegated to Azure in the DNS zone (for example ocp.azure.example.com) + - **resource_group_name** - the Azure resource group where the DNS zone has been defined + + **Note:** A soft link has been created to the **terraform.tfvars** in each of the terraform subdirectories so the configuration is shared between all of them. + +#### Run all the terraform layers automatically + +From the **/workspace/current** directory, run the following: + +``` +./apply-all.sh -a +``` + +The script will run through each of the terraform layers in sequence to provision the entire infrastructure. + +#### Run all the terraform layers manually + +From the **/workspace/current** directory, change directory into each of the layer subdirectories and run the following: + +```shell +terragrunt init +terragrunt apply -auto-approve +``` + +### Obtain login information + +Once the installation is complete, the login details can be obtained using the following steps: +``` +$ az aro list -o table +$ az aro list-credentials -c -g +``` diff --git a/2-standard/1-aro/launch.sh b/2-standard/1-aro/launch.sh new file mode 100755 index 0000000..1d9d282 --- /dev/null +++ b/2-standard/1-aro/launch.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +# IBM GSI Ecosystem Lab + +SCRIPT_DIR="$(cd $(dirname "$0"); pwd -P)" +SRC_DIR="${SCRIPT_DIR}/automation" + +AUTOMATION_BASE=$(basename "${SCRIPT_DIR}") + +if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then + echo "Usage: launch.sh [{docker cmd}] [--pull]" + echo " where:" + echo " {docker cmd} is the docker command that should be used (e.g. docker, podman). Defaults to docker" + echo " --pull is a flag indicating the latest version of the container image should be pulled" + exit 0 +fi + +DOCKER_CMD="docker" +if [[ -n "$1" ]] && [[ "$1" != "--pull" ]]; then + DOCKER_CMD="${1:-docker}" +fi + +if [[ ! -d "${SRC_DIR}" ]]; then + SRC_DIR="${SCRIPT_DIR}" +fi + +# check if colima is installed, and apply dns override if no override file already exists +if command -v colima &> /dev/null +then + if [ ! -f ~/.lima/_config/override.yaml ]; then + echo "applying colima dns override..." + + COLIMA_STATUS="$(colima status 2>&1)" + SUB='colima is running' + if [[ "$COLIMA_STATUS" == *"$SUB"* ]]; then + echo "stopping colima" + colima stop + fi + + echo "writing ~/.lima/_config/override.yaml" + mkdir -p ~/.lima/_config + printf "useHostResolver: false\ndns:\n- 8.8.8.8" > ~/.lima/_config/override.yaml + + if [[ "$COLIMA_STATUS" == *"$SUB"* ]]; then + echo "restarting colima" + colima start + fi + fi +fi + + +DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools:v1.2-v2.2.19" +#IBM DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-ibmcloud:v1.2-v0.4.23" +#AWS DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-aws:v1.2-v0.3.19" +#AZURE DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.4.19" + +SUFFIX=$(echo $(basename ${SCRIPT_DIR}) | base64 | sed -E "s/[^a-zA-Z0-9_.-]//g" | sed -E "s/.*(.{5})/\1/g") +CONTAINER_NAME="cli-tools-${SUFFIX}" + +echo "Cleaning up old container: ${CONTAINER_NAME}" + +${DOCKER_CMD} kill ${CONTAINER_NAME} 1> /dev/null 2> /dev/null +${DOCKER_CMD} rm ${CONTAINER_NAME} 1> /dev/null 2> /dev/null + +ARG_ARRAY=( "$@" ) + +if [[ " ${ARG_ARRAY[*]} " =~ " --pull " ]]; then + echo "Pulling container image: ${DOCKER_IMAGE}" + ${DOCKER_CMD} pull "${DOCKER_IMAGE}" +fi + + +ENV_VARS="" +if [[ -f "credentials.properties" ]]; then + echo "parsing credentials.properties..." + props=$(grep -v '^#' credentials.properties) + while read line ; do + #remove export statement prefixes + CLEAN="$(echo $line | sed 's/export //' )" + + #parse key-value pairs + IFS=' =' read -r KEY VALUE <<< ${CLEAN//\"/ } + + # don't add an empty key + if [[ -n "${KEY}" ]]; then + ENV_VARS="-e $KEY=$VALUE $ENV_VARS" + fi + done <<< "$props" +fi + + +echo "Initializing container ${CONTAINER_NAME} from ${DOCKER_IMAGE}" +${DOCKER_CMD} run -itd --name ${CONTAINER_NAME} \ + --device /dev/net/tun --cap-add=NET_ADMIN \ + -v "${SRC_DIR}:/terraform" \ + -v "workspace-${AUTOMATION_BASE}-${UID}:/workspaces" \ + ${ENV_VARS} \ + -w /terraform \ + ${DOCKER_IMAGE} + +echo "Attaching to running container..." +${DOCKER_CMD} attach ${CONTAINER_NAME} diff --git a/2-standard/1-aro/layers.yaml b/2-standard/1-aro/layers.yaml new file mode 100644 index 0000000..f80483e --- /dev/null +++ b/2-standard/1-aro/layers.yaml @@ -0,0 +1,10 @@ +names_101: "101-azure-vnet-std" +mock_101: "mock" +names_105: "105-azure-aro-std" +mock_105: "mock" +names_200: "200-openshift-gitops" +mock_200: "mock" +names_210: + - "210-azure-default-storage" + - "210-azure-portworx-storage" +names_220: "220-dev-tools" \ No newline at end of file diff --git a/2-standard/1-aro/terragrunt.hcl b/2-standard/1-aro/terragrunt.hcl new file mode 100644 index 0000000..dfb5d46 --- /dev/null +++ b/2-standard/1-aro/terragrunt.hcl @@ -0,0 +1,36 @@ +terraform { + # Connect to VPN if required for terraform (checks the bom.yaml) + before_hook "check_vpn" { + commands = ["apply","plan","destroy","validate","output"] + execute = ["bash", "${get_parent_terragrunt_dir()}/check-vpn.sh"] + run_on_error = true + } + # Reduce number of parallel executions to improve reliability with github actions + extra_arguments "reduced_parallelism" { + commands = get_terraform_commands_that_need_parallelism() + arguments = ["-parallelism=6"] + } + # Include common TFVAR variables + extra_arguments "common_vars" { + commands = get_terraform_commands_that_need_vars() + + required_var_files = [ + "${get_parent_terragrunt_dir()}/cluster.tfvars", + "${get_parent_terragrunt_dir()}/gitops.tfvars" + ] + } +} + +retryable_errors = [ + "(?s).*igc gitops-module.*", + "(?s).*Error.*failed.*timed out waiting for the condition.*", + "(?s).*Error.*timed out waiting for the condition.*", + "(?s).*Error.*Error logging in to.*", + "(?s).*Error creating repo.*", + "(?s).*Error: Kubernetes cluster unreachable.*", + "(?s).x509: certificate signed by unknown authority.*" +] + +retry_sleep_interval_sec = 60 +retry_max_attempts = 5 +skip = true \ No newline at end of file diff --git a/check-vpn.sh b/check-vpn.sh new file mode 100755 index 0000000..a65a94d --- /dev/null +++ b/check-vpn.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +ROOT_DIRECTORY=$(cd $(dirname "$0"); pwd -P) +BOM_DIRECTORY="${PWD}" + +VPN_REQUIRED=$(grep "vpn/required" "${BOM_DIRECTORY}/bom.yaml" | sed -E "s~[^:]+: [\"'](.*)[\"']~\1~g") +USER=$(whoami) + +RUNNING_PROCESSES=$(ps -ef) +VPN_RUNNING=$(echo "${RUNNING_PROCESSES}" | grep "openvpn --config") + +if [[ "${VPN_REQUIRED}" == "true" ]]; then + + if [[ -n "${VPN_RUNNING}" ]]; then + echo "VPN required but it is already running" + elif command -v openvpn 1> /dev/null 2> /dev/null; then + OVPN_FILE=$(find "${ROOT_DIRECTORY}" -name "*.ovpn" | head -1) + + if [[ -z "${OVPN_FILE}" ]]; then + echo "VPN profile not found." + exit 1 + fi + + echo "Connecting to vpn with profile: ${OVPN_FILE}" + if [[ "${UID}" -eq 0 ]]; then + exec 1<&- + exec 2<&- + openvpn --config "${OVPN_FILE}" || true & + elif [[ "${USER}" == "runner" ]]; then # Caters for self hosted runner image + exec 1<&- + exec 2<&- + openvpn --config "${OVPN_FILE}" || true & + else + exec 1<&- + exec 2<&- + sudo openvpn --config "${OVPN_FILE}" || true & + fi + else + echo "VPN connection required but unable to create the connection automatically. Please connect to your vpn instance using the .ovpn profile within the 101-azure-vnet-std directory and re-run apply-all.sh." + exit 1 + fi +else + if [[ -n "${VPN_RUNNING}" ]]; then + echo "VPN not required but it is already running, shutting down" + if [[ "${UID}" -eq 0 ]]; then + VPN_PID=$(ps xua | grep "openvpn --config" | grep -v grep | awk '{print$1}') + kill "${VPN_PID}" + elif [[ "${USER}" == "runner" ]]; then # Caters for self hosted runner image + VPN_PID=$(ps xua | grep "openvpn --config" | grep -v grep | awk '{print$2}') + kill "${VPN_PID}" + else + VPN_PID=$(ps xua | grep "openvpn --config" | grep -v grep | awk '{print$1}') + sudo kill "${VPN_PID}" + fi + else + echo "VPN not required" + fi +fi \ No newline at end of file diff --git a/launch.sh b/launch.sh index 448a398..c5aa355 100755 --- a/launch.sh +++ b/launch.sh @@ -28,11 +28,12 @@ fi echo "Initializing container ${CONTAINER_NAME} from ${DOCKER_IMAGE}" ${DOCKER_CMD} run -itd --name ${CONTAINER_NAME} \ - -v ${SRC_DIR}:/terraform \ - -v workspace:/workspaces \ - ${ENV_FILE} \ - -w /terraform \ - ${DOCKER_IMAGE} + --device /dev/net/tun --cap-add=NET_ADMIN \ + -v ${SRC_DIR}:/terraform \ + -v workspace:/workspaces \ + ${ENV_FILE} \ + -w /terraform \ + ${DOCKER_IMAGE} echo "Attaching to running container..." ${DOCKER_CMD} attach ${CONTAINER_NAME} diff --git a/setup-workspace.sh b/setup-workspace.sh index af33398..5684568 100755 --- a/setup-workspace.sh +++ b/setup-workspace.sh @@ -166,13 +166,13 @@ echo "Setting up workspace for ${FLAVOR} in ${WORKSPACE_DIR}" echo "*****" if [[ -n "${PREFIX_NAME}" ]]; then - PREFIX_NAME="${PREFIX_NAME}-" + PREFIX_NAME="${PREFIX_NAME}" else chars=abcdefghijklmnopqrstuvwxyz0123456789 for i in {1..5}; do NAME+=${chars:RANDOM%${#chars}:1} done - PREFIX_NAME="${NAME}-" + PREFIX_NAME="${NAME}" fi if [[ -z "${GIT_HOST}" ]]; then @@ -201,7 +201,7 @@ fi cp "${SCRIPT_DIR}/apply-all.sh" "${WORKSPACE_DIR}" cp "${SCRIPT_DIR}/plan-all.sh" "${WORKSPACE_DIR}" cp "${SCRIPT_DIR}/destroy-all.sh" "${WORKSPACE_DIR}" -# cp "${SCRIPT_DIR}/check-vpn.sh" "${WORKSPACE_DIR}/check-vpn.sh" +cp "${SCRIPT_DIR}/check-vpn.sh" "${WORKSPACE_DIR}/check-vpn.sh" cp -R "${SCRIPT_DIR}/${FLAVOR_DIR}/.mocks" "${WORKSPACE_DIR}" cp "${SCRIPT_DIR}/${FLAVOR_DIR}/layers.yaml" "${WORKSPACE_DIR}" cp "${SCRIPT_DIR}/${FLAVOR_DIR}/terragrunt.hcl" "${WORKSPACE_DIR}" diff --git a/terraform.tfvars.template-standard-aro b/terraform.tfvars.template-standard-aro new file mode 100644 index 0000000..dbe1dcd --- /dev/null +++ b/terraform.tfvars.template-standard-aro @@ -0,0 +1,32 @@ +## OpenShift Cluster Prefix +cluster_name="PREFIX-std" + +## Name prefix for VNet and other components +name_prefix="PREFIX" + +## Resource group name for the networking components +resource_group_name="PREFIX-rg" + +## Azure region into which to deploy +region="REGION" + +## The number of worker nodes to create +cluster__count=3 + +## The type of worker nodes to create +cluster_flavor="Standard_D4s_v3" + +###################### +#### Portworx storage + +# Uncomment and include the path to the Portworx spec file (refer to https://github.com/cloud-native-toolkit/terraform-azure-portworx) if using the portworx storage +# Make sure this path is visible from where you are running terraform/terragrunt. +# If you are using the container approach, put the spec file into the root path for the cloned repository. This will be visible as /terraform in the container. +# The spec file would then be at /terraform/ within the container. +#azure-portworx_portworx_spec_file="" + +# Alternately, the base64 encoded portworx yaml file can be put into the credentials.properties file. + +## Cluster Banner +## config_banner_text: The text that will appear in the top banner in the cluster +config_banner_text="BANNER" From c1e5049688c7aad330dc4c038763b0443ab0a327 Mon Sep 17 00:00:00 2001 From: rich-ehrhardt Date: Thu, 20 Oct 2022 15:26:07 +1100 Subject: [PATCH 03/13] Restricts testing to just standard Signed-off-by: rich-ehrhardt --- .github/workflows/verify-workflow.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/verify-workflow.yaml b/.github/workflows/verify-workflow.yaml index 763beed..ac03177 100644 --- a/.github/workflows/verify-workflow.yaml +++ b/.github/workflows/verify-workflow.yaml @@ -39,13 +39,14 @@ jobs: max-parallel: 2 matrix: flavor: - - quickstart + #- quickstart + - standard dist: - aro - - ipi + #- ipi storage: - #- default - - portworx + - default + #- portworx certificate: - acme region: From af5ff18786f9bf02f7fe95b45fd0bb0c0c52d6ab Mon Sep 17 00:00:00 2001 From: rich-ehrhardt Date: Fri, 21 Oct 2022 13:22:57 +1100 Subject: [PATCH 04/13] Adds azure region validation Signed-off-by: rich-ehrhardt --- azure-metadata.yaml | 116 ++++++++++++++++++++++++++++++++++++++++++++ setup-workspace.sh | 44 ++++++++++++++++- 2 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 azure-metadata.yaml diff --git a/azure-metadata.yaml b/azure-metadata.yaml new file mode 100644 index 0000000..357132d --- /dev/null +++ b/azure-metadata.yaml @@ -0,0 +1,116 @@ +# The following regions support ARO +flavors: + - name: Quickstart + code: quickstart + - name: Standard + code: standard +storage: + - name: Default + code: default + - name: Portworx + code: portworx +distributions: + - name: OpenShift IPI + code: ipi + - name: Azure Red Hat OpenShift + code: aro +regions: + - name: South Africa North + code: southafricanorth + area: Africa + - name: East Asia + code: eastasia + area: Asia Pacific + - name: South East Asia + code: southeastasia + area: Asia Pacific + - name: Australia Central + code: australiacentral + area: Australia + - name: Australia East + code: australiaeast + area: Australia + - name: Australia Southeast + code: australiasoutheast + area: Australia + - name: Brazil South + code: brazilsouth + area: South America + - name: Canada Central + code: canadacentral + area: Canada + - name: Canada East + code: canadaeast + area: Canada + - name: North Europe + code: northeurope + area: Europe + - name: West Europe + code: westeurope + area: Europe + - name: France Central + code: francecentral + area: Europe + - name: Germany West Central + code: germanywestcentral + area: Europe + - name: Central India + code: centralindia + area: Asia Pacific + - name: South India + code: southindia + area: Asia Pacific + - name: Japan East + code: japaneast + area: Asia Pacific + - name: Japan West + code: japanwest + area: Asia Pacific + - name: Korea Central + code: koreacentral + area: Asia Pacific + - name: Qatar Central + code: qatarcentral + area: Middle East + - name: Sweden Central + code: swedencentral + area: Europe + - name: Switzerland North + code: switzerlandnorth + area: Europe + - name: UAE North + code: uaenorth + area: Middle East + - name: UK South + code: uksouth + area: Europe + - name: UK West + code: ukwest + area: Europe + - name: Central US + code: southcentralus + area: US + - name: East US + code: eastus + area: US + - name: East US 2 + code: eastus2 + area: US + - name: North Central US + code: northcentralus + area: US + - name: South Central US + code: southcentralus + area: US + - name: West Central US + code: westcentralus + area: US + - name: West US + code: westus + area: US + - name: West US 2 + code: westus2 + area: US + - name: West US 3 + code: westus3 + area: US diff --git a/setup-workspace.sh b/setup-workspace.sh index 5684568..ed18ad6 100755 --- a/setup-workspace.sh +++ b/setup-workspace.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIR=$(cd $(dirname $0); pwd -P) +METADATA_FILE="${SCRIPT_DIR}/azure-metadata.yaml" ## For now default to quickstart #FLAVOR="quickstart" @@ -15,8 +16,8 @@ Usage() echo echo "Usage: setup-workspace.sh -f FLAVOR -s STORAGE -c CERTIFICATE [-n PREFIX_NAME] [-r REGION]" echo " options:" - echo " -f the flavor to use (quickstart, standard, advanced)" - echo " -d OpenShift distribution (aro, ipi)" + echo " -f the flavor to use (quickstart, standard)" + echo " -d OpenShift distribution (aro, ipi). IPI is currently only available with quickstart." echo " -s the storage option to use (portworx or default)" echo " -c certificate to use (acme or byo) - only applicable for IPI distributions." echo " -n (optional) prefix that should be used for all variables" @@ -103,6 +104,44 @@ else done fi +# Validate flavor and distribution +if [[ "${FLAVOR}" == "standard" ]] && [[ "${DIST}" == "ipi" ]]; then + echo "Openshift IPI is currently only supported with quickstart architecture. Please choose a different combination." + exit +fi + +# Validate region +if [[ -z "$(cat ${METADATA_FILE} | yq ".regions[] | select(.code == \"${REGION}\") | .code" )" ]]; then + echo "Supplied region ${REGION} is not a valid Azure region for an OpenShift deployment." + echo "Please select a valid deployment region." + SELECT_AREA=true +elif [[ -z "${REGION}" ]]; then + echo "Please select the deployment region." + SELECT_AREA=true +else + SELECT_AREA=false +fi + +if $SELECT_AREA ; then + AREAS=$(cat ${METADATA_FILE} | yq '.regions[].area' | tr ' ' '_' | sort -u ) + PS3="Select the deployment area: " + select area in ${AREAS[@]}; do + if [[ -n "${area}" ]]; then + AREA=$(echo ${area} | tr '_' ' ') + break + fi + done + + REGIONS=$(cat ${METADATA_FILE} | yq ".regions[] | select(.area == \"${AREA}\") | .name" | tr ' ' '_') + PS3="Select the region within ${AREA}: " + select region in ${REGIONS[@]}; do + if [[ -n "${region}" ]]; then + REGION=$(cat ${METADATA_FILE} | yq ".regions[] | select(.name == \"$(echo $region | tr '_' ' ')\") | .code") + break + fi + done +fi + # Get storage option STORAGE_OPTIONS=($(find "${SCRIPT_DIR}/${FLAVOR_DIR}" -type d -maxdepth 1 -name "210-*" | grep "${SCRIPT_DIR}/${FLAVOR_DIR}/" | sed -E "s~${SCRIPT_DIR}/${FLAVOR_DIR}/~~g" | sort)) @@ -247,3 +286,4 @@ do done echo "move to ${WORKSPACE_DIR} this is where your automation is configured" + From 62ac1999e336f717d705475f9ac2f273b111203d Mon Sep 17 00:00:00 2001 From: rich-ehrhardt Date: Fri, 21 Oct 2022 14:45:16 +1100 Subject: [PATCH 05/13] Updates quickstart readme Signed-off-by: rich-ehrhardt --- 1-quickstart/1-aro/README.md | 4 ++-- 1-quickstart/1-aro/architecture.png | Bin 0 -> 210323 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 1-quickstart/1-aro/architecture.png diff --git a/1-quickstart/1-aro/README.md b/1-quickstart/1-aro/README.md index b89391c..25c1ff9 100644 --- a/1-quickstart/1-aro/README.md +++ b/1-quickstart/1-aro/README.md @@ -19,8 +19,8 @@ The automation is delivered in a number of layers that are applied in order. Lay -105 - IBM VPC OpenShift -This layer provisions the Azure infrastructure and OpenShift. It will create a new VNet and other networking components required to support the OpenShift cluster. An existing registered DNS zone for the required domain name is required (refer to prerequisites). +105 - Azure ARO +This layer provisions the Azure infrastructure and OpenShift. It will create a new VNet and other networking components required to support the OpenShift cluster.

Network