diff --git a/.github/workflows/verify-workflow.yaml b/.github/workflows/verify-workflow.yaml index 6b69f88..a1dbc5c 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-azure:v1.2-v0.4.20 + image: quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.6.0 options: --privileged --user root strategy: diff --git a/.gitignore b/.gitignore index 32744a1..f834918 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ px-spec.yaml *.tgz **/certs/* + +.stop diff --git a/1-quickstart/1-aro/105-azure-aro/105-azure-aro.auto.tfvars b/1-quickstart/1-aro/105-azure-aro/105-azure-aro.auto.tfvars index e367246..d458c87 100644 --- a/1-quickstart/1-aro/105-azure-aro/105-azure-aro.auto.tfvars +++ b/1-quickstart/1-aro/105-azure-aro/105-azure-aro.auto.tfvars @@ -19,3 +19,9 @@ ## name_prefix: The name of the vpc resource #name_prefix="" +## pull_secret: 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 +#pull_secret="" + +## pull_secret_file: 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 +#pull_secret_file="" + diff --git a/1-quickstart/1-aro/105-azure-aro/apply.sh b/1-quickstart/1-aro/105-azure-aro/apply.sh index e64c76a..cc88204 100755 --- a/1-quickstart/1-aro/105-azure-aro/apply.sh +++ b/1-quickstart/1-aro/105-azure-aro/apply.sh @@ -4,7 +4,7 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) VARIABLES_FILE="${1}" if [[ -z "${VARIABLES_FILE}" ]]; then - VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" + VARIABLES_FILE="variables.yaml" fi YQ=$(command -v yq4 || command -v yq) @@ -13,11 +13,25 @@ if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g" 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" +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 "" @@ -27,17 +41,18 @@ 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 // ""' -) +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" - variable_name="TF_VAR_${name}" + 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 '.variables[] | select(.name == env(NAME)) | .value // ""' -) + 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 @@ -60,15 +75,44 @@ cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while rea value=${value:-$default_value} done - echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + 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}" -cd ${SCRIPT_DIR}/terraform +source credentials.properties + +cd terraform terraform init terraform apply diff --git a/1-quickstart/1-aro/105-azure-aro/bom.yaml b/1-quickstart/1-aro/105-azure-aro/bom.yaml index a30f682..da3c613 100644 --- a/1-quickstart/1-aro/105-azure-aro/bom.yaml +++ b/1-quickstart/1-aro/105-azure-aro/bom.yaml @@ -24,7 +24,7 @@ spec: - 10.0.0.0/20 - name: azure-vnet-subnets alias: master-subnet - version: v1.3.8 + version: v1.3.10 variables: - name: label value: master @@ -37,7 +37,7 @@ spec: - Microsoft.Storage - name: azure-vnet-subnets alias: worker-subnet - version: v1.3.8 + version: v1.3.10 variables: - name: label value: worker @@ -50,7 +50,7 @@ spec: - Microsoft.Storage - name: azure-aro alias: cluster - version: v1.0.0 + version: v2.0.0 dependencies: - name: master-subnet ref: master-subnet @@ -81,3 +81,17 @@ spec: type: string description: The name of the vpc resource defaultValue: '' + - name: 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 + defaultValue: '' + - name: 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 + defaultValue: '' diff --git a/1-quickstart/1-aro/105-azure-aro/docs/azure-aro.md b/1-quickstart/1-aro/105-azure-aro/docs/azure-aro.md index 101f5c8..d404b2b 100644 --- a/1-quickstart/1-aro/105-azure-aro/docs/azure-aro.md +++ b/1-quickstart/1-aro/105-azure-aro/docs/azure-aro.md @@ -3,20 +3,29 @@ ## 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) +- terraform-util-clis - to setup CLI utils for build +- terraform-ocp-login - to login to the cluster once it is built +- random_domain - generates a random domain name +- null_resource az_login - to login to the az cli with the supplied credentials, or use existing login +- external aro_rp - to obtain OpenShift resource provider details +- null_resource service_principal - to create and destroy a service principal for cluster to use to call Azure API +- azurerm_key_vault - if a key_vault_id is not provided, this will create a new key vault for the service principal details +- azurerm_key_vault_secret - to store the service principal details +- azurerm_role_assignment - assigns required roles to service principal and resource provider +- azapi_resource - CRUD for the ARO cluster +- external aro - obtains details of the created cluster +- time_sleep - a delay to allow the cluster to settle ### Software dependencies -- terraform CLI >= 1.2.6 -- Azure CLI (az) >= 2.39.0 +- terraform CLI >= 1.2.6 +- Azure CLI (az) >= 2.42.0 (must be in the path environment variable) ### Terraform providers - Terraform >= 0.15.0 -- Azure provider >= 3.0.0 +- Azure provider (azurerm) >= 3.3.0 +- Azure API provider (azapi) >= 1.0.0 ### Module dependencies @@ -27,9 +36,17 @@ This module makes use of the output from other modules: ## Prerequisites -### Option 1 - Use a service principal +### Common -The service principal needs the following roles assigned +Ensure that the subscription has the `Microsoft.RedHatOpenShift` provider namespace registerd. +To do so: + ``` + $ az provider register --namespace "Microsoft.RedHatOpenShift" + ``` + +### Azure Login Option 1 - Use a service principal + +Use this option with automated execution. The service principal needs the following roles assigned - In the active directory, application and user administrator permissions - User Administrator @@ -68,9 +85,46 @@ The service principal needs the following roles assigned 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. +1. Export the service principal details are environment variables. + + ``` + $ export TF_VAR_subscription_id= + $ export TF_VAR_tenant_id= + $ export TF_VAR_client_id= + $ export TF_VAR_client_secret= + ``` + +1. Set the variables in the provider block to use those credentials + ```hcl-terraform + provider "azurerm" { + features {} + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id + } + ``` + +### Azure Login Option 2 - Use your Azure user id + +Use this option if running from your terminal. Uses your Azure user. +***Note that your Azure user must have contributor and user access administrator rights to the subscription*** +1. Login to the az cli from within the container before proceeding with terraform actions. + ``` + $ az login + ``` +1. If you have more than one subscription, set the relevant subscription to be used. + ``` + $ az account set --subscription="" + ``` + where is the id of the subscription to be utilized. + +1. Do not include the login details in the provider.tf file in terraform + ```hcl-terraform + provider "azurerm" { + features {} + } + ``` ## Example Usage @@ -119,17 +173,13 @@ 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 + worker_subnet_id = module.worker-subnet.id + + encrypt = true } ``` @@ -137,21 +187,15 @@ module "aro" { ### Inputs -### Inputs - This module has the following input variables: -| Variable | Mandatory / Optional | Default Value | Description | +| Variable | Default Value | Mandatory / Optional | 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 | +| resource_group_name | | Mandatory | The resource group of the network (VNet and subnet) components. A new resource group will be created for the cluster. The location of the cluster will be the same as this resource group. | | 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_prefix | | Mandatory | Name to prefix the created resources | +| client_secret | "" | Optional | The secret of the service principal to be used for the cluster creation and ongoing management. Provide if using a service principal for azurerm login. | | 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 | @@ -162,6 +206,12 @@ This module has the following input variables: | 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 | +| key_vault_id | "" | Optional | Existing key vault id to use (will create a new one if not provided) | +| encrypt | false | Optional | Flag to encrypt the master and worker nodes with server side encryption | +| pod_cidr | 10.128.0.0/14 | Optional | CIDR for the internal pod subnet | +| service_cidr | 172.30.0.0/16 | Optional | CIDR for the internal services subnet | +| fips | false | Optional | Flag to use FIPS validated modules | +| tags | {} | Optional | List of tags to be included as name value key pairs | ### Outputs @@ -177,4 +227,5 @@ The module outputs the following values: | username | The login username for the cluster | | password | The login password for the cluster | | serverURL | The API URL for the cluster | +| console_url | The URL of the web console 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/1-quickstart/1-aro/105-azure-aro/docs/azure-vnet-subnets.md b/1-quickstart/1-aro/105-azure-aro/docs/azure-vnet-subnets.md index e1400a0..a09d0e8 100644 --- a/1-quickstart/1-aro/105-azure-aro/docs/azure-vnet-subnets.md +++ b/1-quickstart/1-aro/105-azure-aro/docs/azure-vnet-subnets.md @@ -19,11 +19,12 @@ The module depends on the following software components: #### Command-line tools -- terraform >= v0.15 +- terraform >= v0.15 and < v1.3 +***Note that this module does nto support terraform version 1.3 and above*** #### Terraform providers -- Azure provider +- Azure provider >= 3.27.0 ### Module dependencies @@ -83,6 +84,25 @@ module "subnets" { } ``` +## Read Only Usage + +The module may be utilised in a read-only mode by setting provision=false. + +Doing so will cause the module to attempt to read an existing subnet that it is provided. Provide the resource group name, region, vnet name and subnet name in such circumstances to return the subnet details. ***Note that this method requires a single subnet name at a time*** + +For example: +```hcl-terraform +module "subnet-query" { + source = "/home/richard/github/terraform-azure-subnets" + + provision = false + resource_group_name = module.resource_group.name + vnet_name = module.vnet.name + region = module.resource_group.region + subnet_name = "test-subnet" +} +``` + ## Input Variables This module has the following input variables: @@ -98,6 +118,7 @@ This module has the following input variables: | 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 diff --git a/1-quickstart/1-aro/105-azure-aro/main.tf b/1-quickstart/1-aro/105-azure-aro/main.tf index 4e5b14a..d437f16 100644 --- a/1-quickstart/1-aro/105-azure-aro/main.tf +++ b/1-quickstart/1-aro/105-azure-aro/main.tf @@ -1,35 +1,36 @@ module "cluster" { - source = "github.com/cloud-native-toolkit/terraform-azure-aro?ref=v1.0.0" + source = "github.com/cloud-native-toolkit/terraform-azure-aro?ref=v2.0.0" - _count = var.cluster__count - auth_group_id = var.cluster_auth_group_id - client_id = var.client_id client_secret = var.client_secret disable_public_endpoint = var.cluster_disable_public_endpoint - disk_size = var.cluster_disk_size - flavor = var.cluster_flavor + encrypt = var.cluster_encrypt + fips = var.cluster_fips + key_vault_id = var.cluster_key_vault_id label = var.cluster_label master_flavor = var.cluster_master_flavor master_subnet_id = module.master-subnet.id name = var.cluster_name name_prefix = var.name_prefix - openshift_version = var.cluster_openshift_version os_type = var.cluster_os_type + pod_cidr = var.cluster_pod_cidr provision = var.cluster_provision pull_secret = var.pull_secret pull_secret_file = var.pull_secret_file - region = var.region resource_group_name = module.resource_group.name - subscription_id = var.subscription_id - tenant_id = var.tenant_id + service_cidr = var.cluster_service_cidr + tags = var.cluster_tags vnet_name = module.vnet.name + worker_count = var.cluster_worker_count + worker_disk_size = var.cluster_worker_disk_size + worker_flavor = var.cluster_worker_flavor worker_subnet_id = module.worker-subnet.id } module "master-subnet" { - source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.8" + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" 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 @@ -61,10 +62,11 @@ module "vnet" { resource_group_name = module.resource_group.name } module "worker-subnet" { - source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.8" + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" 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 diff --git a/1-quickstart/1-aro/105-azure-aro/output.tf b/1-quickstart/1-aro/105-azure-aro/output.tf new file mode 100644 index 0000000..eea3b0f --- /dev/null +++ b/1-quickstart/1-aro/105-azure-aro/output.tf @@ -0,0 +1,183 @@ +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 "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 + sensitive = true +} +output "cluster_console_url" { + description = "The URL for the web console of the cluster" + value = module.cluster.console_url +} +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 +} diff --git a/1-quickstart/1-aro/105-azure-aro/outputs.tf b/1-quickstart/1-aro/105-azure-aro/outputs.tf deleted file mode 100644 index 8021bfb..0000000 --- a/1-quickstart/1-aro/105-azure-aro/outputs.tf +++ /dev/null @@ -1,45 +0,0 @@ -output "id" { - value = module.cluster.id - description = "Id of the ARO cluster" -} - -output "name" { - value = module.cluster.name - description = "Name of the ARO cluster" -} - -output "resource_group_name" { - value = module.cluster.resource_group_name - description = "Resource group containing the ARO cluster" -} - -output "region" { - value = module.cluster.region - description = "Region containing the ARO cluster" -} - -output "config_file_path" { - value = module.cluster.config_file_path - description = "Path to the config file for the ARO cluster" -} - -output "token" { - value = module.cluster.token - description = "CLI login token for the ARO cluster" -} - -output "username" { - value = module.cluster.username - description = "Login username for the ARO cluster" -} - -output "password" { - value = module.cluster.password - description = "Password for the ARO cluster" - sensitive = true -} - -output "server_url" { - value = module.cluster.serverURL - description = "The url used to connect to the API of the cluster" -} \ No newline at end of file diff --git a/1-quickstart/1-aro/105-azure-aro/providers.tf b/1-quickstart/1-aro/105-azure-aro/providers.tf index 4b45870..bac303b 100644 --- a/1-quickstart/1-aro/105-azure-aro/providers.tf +++ b/1-quickstart/1-aro/105-azure-aro/providers.tf @@ -1,8 +1,8 @@ provider "azurerm" { - features { - - } + + features {} + subscription_id = var.subscription_id client_id = var.client_id diff --git a/1-quickstart/1-aro/105-azure-aro/variables.tf b/1-quickstart/1-aro/105-azure-aro/variables.tf index 56100dd..0c70d57 100644 --- a/1-quickstart/1-aro/105-azure-aro/variables.tf +++ b/1-quickstart/1-aro/105-azure-aro/variables.tf @@ -19,18 +19,22 @@ variable "region" { variable "subscription_id" { type = string description = "the value of subscription_id" + default = null } variable "client_id" { type = string description = "the value of client_id" + default = null } variable "client_secret" { type = string description = "the value of client_secret" + default = null } variable "tenant_id" { type = string description = "the value of tenant_id" + default = null } variable "vnet_name" { type = string @@ -101,6 +105,11 @@ variable "master-subnet_disable_private_link_endpoint_network_policies" { 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" @@ -136,22 +145,22 @@ variable "worker-subnet_disable_private_link_endpoint_network_policies" { description = "Flag to disable private link endpoint 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 "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_master_flavor" { type = string description = "The size of the VMs for the master nodes" default = "Standard_D8s_v3" } -variable "cluster_flavor" { +variable "cluster_worker_flavor" { type = string description = "The size of the VMs for the worker nodes" default = "Standard_D4s_v3" } -variable "cluster__count" { +variable "cluster_worker_count" { type = number description = "The number of compute worker nodes" default = 3 @@ -171,17 +180,12 @@ variable "cluster_name" { 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" { +variable "cluster_worker_disk_size" { type = number description = "The size in GB of the disk for each worker node" default = 128 @@ -201,3 +205,33 @@ variable "cluster_label" { description = "The label used to generate the cluster name" default = "cluster" } +variable "cluster_key_vault_id" { + type = string + description = "THe Azure id of an existing key vault to use to store ARO Service Principal credentials (default = \"\")" + default = "" +} +variable "cluster_encrypt" { + type = bool + description = "Flag to encrypt the VM disks (default = false)" + default = false +} +variable "cluster_pod_cidr" { + type = string + description = "CIDR for the POD subnet (default = \"10.128.0.0/14\")" + default = "10.128.0.0/14" +} +variable "cluster_service_cidr" { + type = string + description = "CIDR for the services subnet (default = \"172.30.0.0/16\")" + default = "172.30.0.0/16" +} +variable "cluster_fips" { + type = bool + description = "Flag to determine if FIPS validated modules should be utilized (default = false)" + default = false +} +variable "cluster_tags" { + type = map(string) + description = "List of tags to be included as \"name\":\"value\" pairs (default = {})" + default = {} +} diff --git a/1-quickstart/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars b/1-quickstart/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars index c46b96f..5f3aa26 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars +++ b/1-quickstart/1-aro/200-openshift-gitops/200-openshift-gitops.auto.tfvars @@ -1,12 +1,6 @@ ## 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="" @@ -25,3 +19,9 @@ ## gitops_repo_repo: The short name of the repository (i.e. the part after the org/group name) #gitops_repo_repo="" +## server_url: The url for the OpenShift api +#server_url="" + +## cluster_login_token: Token used for authentication +#cluster_login_token="" + diff --git a/1-quickstart/1-aro/200-openshift-gitops/apply.sh b/1-quickstart/1-aro/200-openshift-gitops/apply.sh index e64c76a..cc88204 100755 --- a/1-quickstart/1-aro/200-openshift-gitops/apply.sh +++ b/1-quickstart/1-aro/200-openshift-gitops/apply.sh @@ -4,7 +4,7 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) VARIABLES_FILE="${1}" if [[ -z "${VARIABLES_FILE}" ]]; then - VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" + VARIABLES_FILE="variables.yaml" fi YQ=$(command -v yq4 || command -v yq) @@ -13,11 +13,25 @@ if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g" 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" +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 "" @@ -27,17 +41,18 @@ 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 // ""' -) +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" - variable_name="TF_VAR_${name}" + 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 '.variables[] | select(.name == env(NAME)) | .value // ""' -) + 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 @@ -60,15 +75,44 @@ cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while rea value=${value:-$default_value} done - echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + 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}" -cd ${SCRIPT_DIR}/terraform +source credentials.properties + +cd terraform terraform init terraform apply diff --git a/1-quickstart/1-aro/200-openshift-gitops/bom.yaml b/1-quickstart/1-aro/200-openshift-gitops/bom.yaml index d77ae60..bec29b4 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/bom.yaml +++ b/1-quickstart/1-aro/200-openshift-gitops/bom.yaml @@ -13,15 +13,9 @@ metadata: 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 + version: v3.2.4 variables: - name: name value: gitea @@ -31,15 +25,9 @@ spec: 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-cluster-config + alias: config + version: v1.1.1 - name: gitops-console-link-job alias: gitops-console-link-job version: v1.5.1 @@ -50,23 +38,28 @@ spec: variables: - name: name value: toolkit - - name: util-clis - version: v1.17.2 + - name: gitops-repo + alias: gitops_repo + version: v1.23.1 + - name: argocd-bootstrap + alias: argocd-bootstrap + version: v1.12.0 + variables: + - name: create_webhook + value: true + - name: ocp-login + alias: cluster + version: v1.6.0 - name: olm - version: v1.3.2 + version: v1.3.5 + - name: util-clis + version: v1.18.1 - 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: >- @@ -100,3 +93,10 @@ spec: description: >- The short name of the repository (i.e. the part after the org/group name) + - 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/1-quickstart/1-aro/200-openshift-gitops/dependencies.dot b/1-quickstart/1-aro/200-openshift-gitops/dependencies.dot index 89b4ec2..0c7d29d 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/dependencies.dot +++ b/1-quickstart/1-aro/200-openshift-gitops/dependencies.dot @@ -1,30 +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_namespace (namespace)" -> "cluster (ocp-login)" +"gitea_namespace (namespace)" +"cluster (ocp-login)" "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)" +"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)" "toolkit_namespace (gitops-namespace)" -> "gitops_repo (gitops-repo)" "toolkit_namespace (gitops-namespace)" +"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)" "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/1-quickstart/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md b/1-quickstart/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md index 8079c97..3014600 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md +++ b/1-quickstart/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md @@ -1,39 +1,66 @@ -# Cluster config gitops module +# Cluster Config module + +Module to populate a gitops repository with base configuration of the Red Hat OpenShift cluster (notification banner, help menus, etc) -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 version -- terraform - v14 -- kubectl +- \>= v0.15 ### Terraform providers -None -## Module dependencies +- gitops (cloud-native-toolkit/gitops) -This module makes use of the output from other modules: +### Module dependencies -- Gitops - github.com/cloud-native-toolkit/terraform-tools-gitops.git -- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + +- gitops - [github.com/cloud-native-toolkit/terraform-tools-gitops.git](https://github.com/cloud-native-toolkit/terraform-tools-gitops.git) (>= 1.1.0) +- namespace - [github.com/cloud-native-toolkit/terraform-gitops-namespace.git](https://github.com/cloud-native-toolkit/terraform-gitops-namespace.git) (>= 1.0.0) ## Example usage -```hcl-terraform -module "cluster-config" { - source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config.git" +```hcl +module "gitops-cluster-config" { + source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config" - 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 + banner_background_color = var.gitops-cluster-config_banner_background_color + banner_text = var.gitops-cluster-config_banner_text + banner_text_color = var.gitops-cluster-config_banner_text_color + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.namespace.name + server_name = module.gitops_repo.server_name } + ``` +## Module details + +### Inputs + +| Name | Description | Required | Default | Source | +|------|-------------|---------|----------|--------| +| gitops_config | Config information regarding the gitops repo structure | true | | gitops.gitops_config | +| git_credentials | The credentials for the gitops repo(s) | true | | gitops.git_credentials | +| namespace | The namespace where the application should be deployed | true | | namespace.name | +| server_name | The name of the server | false | default | gitops.server_name | +| banner_background_color | The background color of the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000). | false | purple | | +| banner_text_color | The text color for the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000). | false | white | | +| banner_text | The text that will appear in the top banner in the cluster | true | | | + +### Outputs + + +None + +## Resources + +- [Documentation](https://operate.cloudnativetoolkit.dev) +- [Module catalog](https://modules.cloudnativetoolkit.dev) + +> License: Apache License 2.0 | Generated by iascable (3.0.0-beta.10) diff --git a/1-quickstart/1-aro/200-openshift-gitops/docs/olm.md b/1-quickstart/1-aro/200-openshift-gitops/docs/olm.md index 4616b71..85fe38a 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/docs/olm.md +++ b/1-quickstart/1-aro/200-openshift-gitops/docs/olm.md @@ -1,29 +1,66 @@ + # 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. +Installs Operator Lifecycle Manager in the cluster + +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. + + +## Software dependencies + +The module depends on the following software components: + +### Terraform version + +- \>= v0.15 + +### Terraform providers + +- clis (cloud-native-toolkit/clis) + +### Module dependencies + +- cluster - interface github.com/cloud-native-toolkit/automation-modules#cluster ## 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" +[Refer to examples for more details](test/stages) - cluster_config_file = "~/.kube/config" - cluster_version = "3.11" - cluster_type = "ocp3" +``` +module "olm" { + source = "github.com/cloud-native-toolkit/terraform-k8s-olm" + + cluster_config_file = module.cluster.config_file_path + cluster_type = module.cluster.platform.type_code + cluster_version = module.cluster.platform.version } ``` -Another example +## Module details -```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" +### Inputs - cluster_config_file = module.dev_cluster.config_file_path - cluster_version = module.dev_cluster.version - cluster_type = var.cluster_type -} -``` +| Name | Description | Required | Default | Source | +|------|-------------|---------|----------|--------| +| cluster_type | The type of cluster (openshift or kubernetes) | true | | cluster.platform.type_code | +| cluster_version | The version of cluster | true | | cluster.platform.version | +| cluster_config_file | Cluster config file for Kubernetes cluster. | true | | cluster.config_file_path | +| olm_version | The version of olm that will be installed | | v0.18.1 | | + + +### Outputs + +| Name | Description | +|------|-------------| +| olm_namespace | Namespace where OLM is running. The value will be different between OCP 4.3 and IKS/OCP 3.11 | +| target_namespace | Namespace where operatoes will be installed | +| operator_namespace | Name space where catalog is running - and subscriptions need to be made | + + +## Resources + +- [Documentation](https://operate.cloudnativetoolkit.dev) +- [Module catalog](https://modules.cloudnativetoolkit.dev) + +> License: Apache License 2.0 | Generated by iascable (2.25.5) diff --git a/1-quickstart/1-aro/200-openshift-gitops/main.tf b/1-quickstart/1-aro/200-openshift-gitops/main.tf index 94704e7..30556d2 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/main.tf +++ b/1-quickstart/1-aro/200-openshift-gitops/main.tf @@ -55,14 +55,14 @@ module "gitea" { username = var.gitea_username } module "gitea_namespace" { - source = "github.com/cloud-native-toolkit/terraform-k8s-namespace?ref=v3.2.3" + source = "github.com/cloud-native-toolkit/terraform-k8s-namespace?ref=v3.2.4" 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" + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.23.1" branch = var.gitops_repo_branch debug = var.debug @@ -95,7 +95,7 @@ module "gitops-console-link-job" { 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" + source = "github.com/cloud-native-toolkit/terraform-k8s-olm?ref=v1.3.5" cluster_config_file = module.cluster.config_file_path cluster_type = module.cluster.platform.type_code @@ -122,7 +122,7 @@ module "toolkit_namespace" { } module "util-clis" { source = "cloud-native-toolkit/clis/util" - version = "1.17.2" + version = "1.18.1" bin_dir = var.util-clis_bin_dir clis = var.util-clis_clis == null ? null : jsondecode(var.util-clis_clis) diff --git a/1-quickstart/1-aro/200-openshift-gitops/output.tf b/1-quickstart/1-aro/200-openshift-gitops/output.tf new file mode 100644 index 0000000..69863ff --- /dev/null +++ b/1-quickstart/1-aro/200-openshift-gitops/output.tf @@ -0,0 +1,248 @@ +output "gitea_namespace_name" { + description = "Namespace name" + value = module.gitea_namespace.name +} +output "gitea_namespace" { + description = "The namespace where the Gitea instance has been provisioned" + value = module.gitea.namespace +} +output "gitea_username" { + description = "The username of the Gitea admin user" + value = module.gitea.username +} +output "gitea_password" { + description = "The password of the Gitea admin user" + value = module.gitea.password + sensitive = true +} +output "gitea_token" { + description = "The api token of the Gitea admin user" + value = module.gitea.token + sensitive = true +} +output "gitea_host" { + description = "The host name of the gitea server" + value = module.gitea.host +} +output "gitea_org" { + description = "The host name of the gitea server" + value = module.gitea.org +} +output "gitea_ingress_host" { + description = "The host name of the gitea server" + value = module.gitea.ingress_host +} +output "gitea_ingress_url" { + description = "The url of the gitea server" + value = module.gitea.ingress_url +} +output "gitea_ca_cert" { + description = "Base64 encoded CA certificate for cluster endpoints" + value = module.gitea.ca_cert +} +output "gitops-console-link-job_name" { + description = "The name of the module" + value = module.gitops-console-link-job.name +} +output "gitops-console-link-job_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-console-link-job.branch +} +output "gitops-console-link-job_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-console-link-job.namespace +} +output "gitops-console-link-job_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-console-link-job.server_name +} +output "gitops-console-link-job_layer" { + description = "The layer where the module is deployed" + value = module.gitops-console-link-job.layer +} +output "gitops-console-link-job_type" { + description = "The type of module where the module is deployed" + value = module.gitops-console-link-job.type +} +output "toolkit_namespace_name" { + description = "Namespace name" + value = module.toolkit_namespace.name +} +output "gitops_repo_config_host" { + description = "The host name of the bootstrap git repo" + value = module.gitops_repo.config_host +} +output "gitops_repo_config_org" { + description = "The org name of the bootstrap git repo" + value = module.gitops_repo.config_org +} +output "gitops_repo_config_name" { + description = "The repo name of the bootstrap git repo" + value = module.gitops_repo.config_name +} +output "gitops_repo_config_project" { + description = "The project name of the bootstrap git repo (for Azure DevOps)" + value = module.gitops_repo.config_project +} +output "gitops_repo_config_repo" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo +} +output "gitops_repo_config_repo_url" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo_url +} +output "gitops_repo_config_ca_cert" { + description = "The ca cert for the self-signed certificate used by the gitops repo" + value = module.gitops_repo.config_ca_cert +} +output "gitops_repo_config_username" { + description = "The username for the config repo" + value = module.gitops_repo.config_username +} +output "gitops_repo_config_token" { + description = "The token for the config repo" + value = module.gitops_repo.config_token + sensitive = true +} +output "gitops_repo_config_paths" { + description = "The paths in the config repo" + value = module.gitops_repo.config_paths +} +output "gitops_repo_config_projects" { + description = "The ArgoCD projects for the different layers of the repo" + value = module.gitops_repo.config_projects +} +output "gitops_repo_bootstrap_path" { + description = "The path to the bootstrap configuration" + value = module.gitops_repo.bootstrap_path +} +output "gitops_repo_bootstrap_branch" { + description = "The branch in the gitrepo containing the bootstrap configuration" + value = module.gitops_repo.bootstrap_branch +} +output "gitops_repo_application_repo" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo +} +output "gitops_repo_application_repo_url" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo_url +} +output "gitops_repo_application_username" { + description = "The username for the application repo" + value = module.gitops_repo.application_username +} +output "gitops_repo_application_token" { + description = "The token for the application repo" + value = module.gitops_repo.application_token + sensitive = true +} +output "gitops_repo_application_paths" { + description = "The paths in the application repo" + value = module.gitops_repo.application_paths +} +output "gitops_repo_gitops_config" { + description = "Config information regarding the gitops repo structure" + value = module.gitops_repo.gitops_config +} +output "gitops_repo_git_credentials" { + description = "The credentials for the gitops repo(s)" + value = module.gitops_repo.git_credentials + sensitive = true +} +output "gitops_repo_server_name" { + description = "The name of the cluster that will be configured for gitops" + value = module.gitops_repo.server_name +} +output "gitops_repo_sealed_secrets_cert" { + description = "The certificate used to encrypt sealed secrets" + value = module.gitops_repo.sealed_secrets_cert +} +output "argocd-bootstrap_argocd_namespace" { + description = "The namespace where the ArgoCD instance has been provisioned" + value = module.argocd-bootstrap.argocd_namespace +} +output "argocd-bootstrap_argocd_service_account" { + description = "The namespace where the ArgoCD instance has been provisioned" + value = module.argocd-bootstrap.argocd_service_account +} +output "argocd-bootstrap_sealed_secrets_cert" { + description = "the value of argocd-bootstrap_sealed_secrets_cert" + value = module.argocd-bootstrap.sealed_secrets_cert +} +output "cluster_id" { + description = "ID of the cluster." + value = module.cluster.id +} +output "cluster_ocp_id" { + description = "OpenShift ID of the cluster." + value = module.cluster.ocp_id +} +output "cluster_name" { + description = "Name of the cluster" + value = module.cluster.name +} +output "cluster_region" { + description = "Region of the cluster" + value = module.cluster.region +} +output "cluster_resource_group_name" { + description = "Resource group of the cluster" + value = module.cluster.resource_group_name +} +output "cluster_server_url" { + description = "The url of the control server." + value = module.cluster.server_url +} +output "cluster_username" { + description = "The username of the control server." + value = module.cluster.username +} +output "cluster_password" { + description = "The password of the control server." + value = module.cluster.password + sensitive = true +} +output "cluster_token" { + description = "The token of the control server." + value = module.cluster.token + sensitive = true +} +output "cluster_config_file_path" { + description = "Path to the config file for the cluster." + value = module.cluster.config_file_path +} +output "cluster_platform" { + description = "Configuration values for the cluster platform" + value = module.cluster.platform +} +output "cluster_ca_cert" { + description = "Base64 encoded CA certificate for cluster endpoints" + value = module.cluster.ca_cert +} +output "olm_olm_namespace" { + description = "Namespace where OLM is running. The value will be different between OCP 4.3 and IKS/OCP 3.11" + value = module.olm.olm_namespace +} +output "olm_target_namespace" { + description = "Namespace where operatoes will be installed" + value = module.olm.target_namespace +} +output "olm_operator_namespace" { + description = "Name space where catalog is running - and subscriptions need to be made" + value = module.olm.operator_namespace +} +output "util-clis_bin_dir" { + description = "Directory where the clis were downloaded" + value = module.util-clis.bin_dir +} +output "sealed-secret-cert_private_key" { + description = "the value of sealed-secret-cert_private_key" + value = module.sealed-secret-cert.private_key + sensitive = true +} +output "sealed-secret-cert_cert" { + description = "the value of sealed-secret-cert_cert" + value = module.sealed-secret-cert.cert +} diff --git a/1-quickstart/1-aro/200-openshift-gitops/outputs.tf b/1-quickstart/1-aro/200-openshift-gitops/outputs.tf deleted file mode 100644 index eba03b0..0000000 --- a/1-quickstart/1-aro/200-openshift-gitops/outputs.tf +++ /dev/null @@ -1,19 +0,0 @@ -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/1-quickstart/1-aro/200-openshift-gitops/providers.tf b/1-quickstart/1-aro/200-openshift-gitops/providers.tf index 459ee95..f3c6350 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/providers.tf +++ b/1-quickstart/1-aro/200-openshift-gitops/providers.tf @@ -2,5 +2,28 @@ provider "gitops" { + + bin_dir = module.util-clis.bin_dir + default_host = module.gitea.host + default_org = module.gitea.org + default_username = module.gitea.username + default_token = module.gitea.token + default_ca_cert = module.gitea.ca_cert + host = var.gitops_host + org = var.gitops_org + project = var.gitops_project + repo = var.gitops_repo + username = var.gitops_username + token = var.gitops_token + branch = var.gitops_branch + server_name = var.gitops_server_name + ca_cert = var.gitops_ca_cert + ca_cert_file = var.gitops_ca_cert_file +} +provider "clis" { + + + + } \ No newline at end of file diff --git a/1-quickstart/1-aro/200-openshift-gitops/terragrunt.hcl b/1-quickstart/1-aro/200-openshift-gitops/terragrunt.hcl index 1900cd3..37b9876 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/terragrunt.hcl +++ b/1-quickstart/1-aro/200-openshift-gitops/terragrunt.hcl @@ -33,9 +33,9 @@ dependency "aro" { } inputs = { - server_url = dependency.aro.outputs.server_url - cluster_login_user = dependency.aro.outputs.username - cluster_login_password = dependency.aro.outputs.password - cluster_login_token= dependency.aro.outputs.token + 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/1-quickstart/1-aro/200-openshift-gitops/variables.tf b/1-quickstart/1-aro/200-openshift-gitops/variables.tf index 835717f..cc8043d 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/variables.tf +++ b/1-quickstart/1-aro/200-openshift-gitops/variables.tf @@ -1,3 +1,33 @@ +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 "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)." @@ -12,83 +42,90 @@ variable "config_banner_text" { type = string description = "The text that will appear in the top banner in the cluster" } -variable "server_url" { +variable "gitops_host" { type = string - description = "The url for the OpenShift api" + description = "The host name of the gitops repository (GitHub, Github Enterprise, Gitlab, Bitbucket, Azure DevOps, and Gitea servers are supported)." + default = "" } -variable "cluster_login_user" { +variable "gitops_org" { type = string - description = "Username for login" + description = "The organization on the git server where the repsitory will be located. If not provided the org will default to the username." default = "" } -variable "cluster_login_password" { +variable "gitops_project" { type = string - description = "Password for login" + description = "The Azure DevOps project in the git server. This value is only applied for Azure DevOps servers." default = "" } -variable "cluster_login_token" { +variable "gitops_repo" { 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 + description = "The name of the repository in the org on the git server." + default = "" } -variable "cluster_cluster_version" { +variable "gitops_username" { type = string - description = "[Deprecated] The version of the cluster (passed through to the output)" + description = "The username used to access the git server." default = "" } -variable "cluster_ingress_subdomain" { +variable "gitops_token" { type = string - description = "[Deprecated] The ingress subdomain of the cluster (passed through to the output)" + description = "The token used to access the git server." default = "" } -variable "cluster_tls_secret_name" { +variable "gitops_branch" { type = string - description = "[Deprecated] The name of the secret containing the tls certificates for the ingress subdomain (passed through to the output)" - default = "" + description = "The name of the branch in the gitops repository where the config will be stored." + default = "main" } -variable "cluster_ca_cert" { +variable "gitops_server_name" { type = string - description = "The base64 encoded ca certificate" - default = "" + description = "The name of the server the configuration with which the configuration will be associated." + default = "default" } -variable "cluster_ca_cert_file" { +variable "gitops_ca_cert" { type = string - description = "The path to the file that contains the ca certificate" + description = "The ca certificate used to sign the self-signed certificate used by the git server, if applicable." default = "" } -variable "gitea_namespace_name" { +variable "gitops_ca_cert_file" { 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 + description = "The file containing the ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" } -variable "gitea_instance_name" { +variable "gitops-console-link-job_cluster_ingress_hostname" { type = string - description = "The name for the instance" - default = "gitea" + description = "Ingress hostname of the IKS cluster." + default = "" } -variable "gitea_username" { +variable "gitops-console-link-job_cluster_type" { type = string - description = "The username for the instance" - default = "gitea-admin" + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" } -variable "gitea_password" { +variable "gitops-console-link-job_tls_secret_name" { type = string - description = "The password for the instance" + description = "The name of the secret containing the tls certificate values" default = "" } -variable "gitea_ca_cert_file" { +variable "toolkit_namespace_name" { type = string - description = "The path to the file that contains the ca certificate" - default = "" + 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 "gitops_repo_host" { type = string @@ -164,40 +201,53 @@ variable "argocd-bootstrap_create_webhook" { 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" { +variable "server_url" { type = string - description = "Ingress hostname of the IKS cluster." - default = "" + description = "The url for the OpenShift api" } -variable "gitops-console-link-job_cluster_type" { +variable "cluster_login_user" { type = string - description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" - default = "ocp4" + description = "Username for login" + default = "" } -variable "gitops-console-link-job_tls_secret_name" { +variable "cluster_login_password" { type = string - description = "The name of the secret containing the tls certificate values" + description = "Password for login" default = "" } -variable "toolkit_namespace_name" { +variable "cluster_login_token" { type = string - description = "The value that should be used for the namespace" - default = "toolkit" + description = "Token used for authentication" } -variable "toolkit_namespace_ci" { +variable "cluster_skip" { type = bool - description = "Flag indicating that this namespace will be used for development (e.g. configmaps and secrets)" + description = "Flag indicating that the cluster login has already been performed" 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 "cluster_cluster_version" { + type = string + description = "[Deprecated] The version of the cluster (passed through to the output)" + default = "" } -variable "toolkit_namespace_argocd_namespace" { +variable "cluster_ingress_subdomain" { type = string - description = "The namespace where argocd has been deployed" - default = "openshift-gitops" + 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 "util-clis_bin_dir" { type = string diff --git a/1-quickstart/1-aro/200-openshift-gitops/version.tf b/1-quickstart/1-aro/200-openshift-gitops/version.tf index 5034007..da8ce2a 100644 --- a/1-quickstart/1-aro/200-openshift-gitops/version.tf +++ b/1-quickstart/1-aro/200-openshift-gitops/version.tf @@ -2,6 +2,12 @@ terraform { required_providers { gitops = { source = "cloud-native-toolkit/gitops" + version = "0.11.1" + } + + clis = { + source = "cloud-native-toolkit/clis" + version = "0.2.4" } } diff --git a/1-quickstart/1-aro/210-azure-portworx-storage/terragrunt.hcl b/1-quickstart/1-aro/210-azure-portworx-storage/terragrunt.hcl index bdf75f4..b4badf6 100644 --- a/1-quickstart/1-aro/210-azure-portworx-storage/terragrunt.hcl +++ b/1-quickstart/1-aro/210-azure-portworx-storage/terragrunt.hcl @@ -23,10 +23,10 @@ dependency "aro" { } inputs = { - server_url = dependency.aro.outputs.server_url - cluster_login_user = dependency.aro.outputs.username - cluster_login_password = dependency.aro.outputs.password + server_url = dependency.aro.outputs.cluster_serverURL + cluster_login_user = dependency.aro.outputs.cluster_username + cluster_login_password = dependency.aro.outputs.cluster_password azure-portworx_portworx_spec = local.px_spec azure-portworx_cluster_type = "ARO" - cluster_login_token= dependency.aro.outputs.token + cluster_login_token= dependency.aro.outputs.cluster_token } \ No newline at end of file diff --git a/1-quickstart/1-aro/220-dev-tools/apply.sh b/1-quickstart/1-aro/220-dev-tools/apply.sh index e64c76a..cc88204 100755 --- a/1-quickstart/1-aro/220-dev-tools/apply.sh +++ b/1-quickstart/1-aro/220-dev-tools/apply.sh @@ -4,7 +4,7 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) VARIABLES_FILE="${1}" if [[ -z "${VARIABLES_FILE}" ]]; then - VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" + VARIABLES_FILE="variables.yaml" fi YQ=$(command -v yq4 || command -v yq) @@ -13,11 +13,25 @@ if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g" 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" +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 "" @@ -27,17 +41,18 @@ 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 // ""' -) +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" - variable_name="TF_VAR_${name}" + 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 '.variables[] | select(.name == env(NAME)) | .value // ""' -) + 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 @@ -60,15 +75,44 @@ cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while rea value=${value:-$default_value} done - echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + 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}" -cd ${SCRIPT_DIR}/terraform +source credentials.properties + +cd terraform terraform init terraform apply diff --git a/1-quickstart/1-aro/220-dev-tools/bom.yaml b/1-quickstart/1-aro/220-dev-tools/bom.yaml index 3709901..f337212 100644 --- a/1-quickstart/1-aro/220-dev-tools/bom.yaml +++ b/1-quickstart/1-aro/220-dev-tools/bom.yaml @@ -30,7 +30,7 @@ spec: version: v1.2.0 - name: gitops-repo alias: gitops_repo - version: v1.22.1 + version: v1.23.1 - name: gitops-sonarqube alias: gitops-sonarqube version: v1.3.0 @@ -41,7 +41,7 @@ spec: alias: gitops-tekton-resources version: v2.1.0 - name: util-clis - version: v1.17.2 + version: v1.18.1 - name: gitops-buildah-unprivileged version: v1.1.1 variables: diff --git a/1-quickstart/1-aro/220-dev-tools/main.tf b/1-quickstart/1-aro/220-dev-tools/main.tf index 31eeed2..40d8095 100644 --- a/1-quickstart/1-aro/220-dev-tools/main.tf +++ b/1-quickstart/1-aro/220-dev-tools/main.tf @@ -1,5 +1,5 @@ module "gitops_repo" { - source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.22.1" + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.23.1" branch = var.gitops_repo_branch debug = var.debug @@ -117,7 +117,7 @@ module "tools_namespace" { } module "util-clis" { source = "cloud-native-toolkit/clis/util" - version = "1.17.2" + version = "1.18.1" bin_dir = var.util-clis_bin_dir clis = var.util-clis_clis == null ? null : jsondecode(var.util-clis_clis) diff --git a/1-quickstart/1-aro/220-dev-tools/output.tf b/1-quickstart/1-aro/220-dev-tools/output.tf new file mode 100644 index 0000000..ab4853b --- /dev/null +++ b/1-quickstart/1-aro/220-dev-tools/output.tf @@ -0,0 +1,271 @@ +output "gitops-artifactory_name" { + description = "The name of the module" + value = module.gitops-artifactory.name +} +output "gitops-artifactory_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-artifactory.branch +} +output "gitops-artifactory_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-artifactory.namespace +} +output "gitops-artifactory_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-artifactory.server_name +} +output "gitops-artifactory_layer" { + description = "The layer where the module is deployed" + value = module.gitops-artifactory.layer +} +output "gitops-artifactory_type" { + description = "The type of module where the module is deployed" + value = module.gitops-artifactory.type +} +output "gitops-dashboard_name" { + description = "The name of the module" + value = module.gitops-dashboard.name +} +output "gitops-dashboard_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-dashboard.branch +} +output "gitops-dashboard_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-dashboard.namespace +} +output "gitops-dashboard_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-dashboard.server_name +} +output "gitops-dashboard_layer" { + description = "The layer where the module is deployed" + value = module.gitops-dashboard.layer +} +output "gitops-dashboard_type" { + description = "The type of module where the module is deployed" + value = module.gitops-dashboard.type +} +output "tools_namespace_name" { + description = "Namespace name" + value = module.tools_namespace.name +} +output "gitops-pact-broker_name" { + description = "The name of the module" + value = module.gitops-pact-broker.name +} +output "gitops-pact-broker_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-pact-broker.branch +} +output "gitops-pact-broker_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-pact-broker.namespace +} +output "gitops-pact-broker_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-pact-broker.server_name +} +output "gitops-pact-broker_layer" { + description = "The layer where the module is deployed" + value = module.gitops-pact-broker.layer +} +output "gitops-pact-broker_type" { + description = "The type of module where the module is deployed" + value = module.gitops-pact-broker.type +} +output "gitops_repo_config_host" { + description = "The host name of the bootstrap git repo" + value = module.gitops_repo.config_host +} +output "gitops_repo_config_org" { + description = "The org name of the bootstrap git repo" + value = module.gitops_repo.config_org +} +output "gitops_repo_config_name" { + description = "The repo name of the bootstrap git repo" + value = module.gitops_repo.config_name +} +output "gitops_repo_config_project" { + description = "The project name of the bootstrap git repo (for Azure DevOps)" + value = module.gitops_repo.config_project +} +output "gitops_repo_config_repo" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo +} +output "gitops_repo_config_repo_url" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo_url +} +output "gitops_repo_config_ca_cert" { + description = "The ca cert for the self-signed certificate used by the gitops repo" + value = module.gitops_repo.config_ca_cert +} +output "gitops_repo_config_username" { + description = "The username for the config repo" + value = module.gitops_repo.config_username +} +output "gitops_repo_config_token" { + description = "The token for the config repo" + value = module.gitops_repo.config_token + sensitive = true +} +output "gitops_repo_config_paths" { + description = "The paths in the config repo" + value = module.gitops_repo.config_paths +} +output "gitops_repo_config_projects" { + description = "The ArgoCD projects for the different layers of the repo" + value = module.gitops_repo.config_projects +} +output "gitops_repo_bootstrap_path" { + description = "The path to the bootstrap configuration" + value = module.gitops_repo.bootstrap_path +} +output "gitops_repo_bootstrap_branch" { + description = "The branch in the gitrepo containing the bootstrap configuration" + value = module.gitops_repo.bootstrap_branch +} +output "gitops_repo_application_repo" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo +} +output "gitops_repo_application_repo_url" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo_url +} +output "gitops_repo_application_username" { + description = "The username for the application repo" + value = module.gitops_repo.application_username +} +output "gitops_repo_application_token" { + description = "The token for the application repo" + value = module.gitops_repo.application_token + sensitive = true +} +output "gitops_repo_application_paths" { + description = "The paths in the application repo" + value = module.gitops_repo.application_paths +} +output "gitops_repo_gitops_config" { + description = "Config information regarding the gitops repo structure" + value = module.gitops_repo.gitops_config +} +output "gitops_repo_git_credentials" { + description = "The credentials for the gitops repo(s)" + value = module.gitops_repo.git_credentials + sensitive = true +} +output "gitops_repo_server_name" { + description = "The name of the cluster that will be configured for gitops" + value = module.gitops_repo.server_name +} +output "gitops_repo_sealed_secrets_cert" { + description = "The certificate used to encrypt sealed secrets" + value = module.gitops_repo.sealed_secrets_cert +} +output "gitops-sonarqube_name" { + description = "The name of the module" + value = module.gitops-sonarqube.name +} +output "gitops-sonarqube_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-sonarqube.branch +} +output "gitops-sonarqube_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-sonarqube.namespace +} +output "gitops-sonarqube_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-sonarqube.server_name +} +output "gitops-sonarqube_layer" { + description = "The layer where the module is deployed" + value = module.gitops-sonarqube.layer +} +output "gitops-sonarqube_type" { + description = "The type of module where the module is deployed" + value = module.gitops-sonarqube.type +} +output "gitops-sonarqube_postgresql" { + description = "Properties for an existing postgresql database" + value = module.gitops-sonarqube.postgresql +} +output "gitops-swagger-editor_name" { + description = "The name of the module" + value = module.gitops-swagger-editor.name +} +output "gitops-swagger-editor_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-swagger-editor.branch +} +output "gitops-swagger-editor_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-swagger-editor.namespace +} +output "gitops-swagger-editor_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-swagger-editor.server_name +} +output "gitops-swagger-editor_layer" { + description = "The layer where the module is deployed" + value = module.gitops-swagger-editor.layer +} +output "gitops-swagger-editor_type" { + description = "The type of module where the module is deployed" + value = module.gitops-swagger-editor.type +} +output "gitops-tekton-resources_name" { + description = "The name of the module" + value = module.gitops-tekton-resources.name +} +output "gitops-tekton-resources_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-tekton-resources.branch +} +output "gitops-tekton-resources_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-tekton-resources.namespace +} +output "gitops-tekton-resources_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-tekton-resources.server_name +} +output "gitops-tekton-resources_layer" { + description = "The layer where the module is deployed" + value = module.gitops-tekton-resources.layer +} +output "gitops-tekton-resources_type" { + description = "The type of module where the module is deployed" + value = module.gitops-tekton-resources.type +} +output "util-clis_bin_dir" { + description = "Directory where the clis were downloaded" + value = module.util-clis.bin_dir +} +output "gitops-buildah-unprivileged_name" { + description = "The name of the module" + value = module.gitops-buildah-unprivileged.name +} +output "gitops-buildah-unprivileged_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-buildah-unprivileged.branch +} +output "gitops-buildah-unprivileged_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-buildah-unprivileged.namespace +} +output "gitops-buildah-unprivileged_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-buildah-unprivileged.server_name +} +output "gitops-buildah-unprivileged_layer" { + description = "The layer where the module is deployed" + value = module.gitops-buildah-unprivileged.layer +} +output "gitops-buildah-unprivileged_type" { + description = "The type of module where the module is deployed" + value = module.gitops-buildah-unprivileged.type +} diff --git a/1-quickstart/1-aro/220-dev-tools/providers.tf b/1-quickstart/1-aro/220-dev-tools/providers.tf index 459ee95..9aa08ee 100644 --- a/1-quickstart/1-aro/220-dev-tools/providers.tf +++ b/1-quickstart/1-aro/220-dev-tools/providers.tf @@ -2,5 +2,28 @@ provider "gitops" { + + bin_dir = module.util-clis.bin_dir + default_host = var.gitops_default_host + default_org = var.gitops_default_org + default_username = var.gitops_default_username + default_token = var.gitops_default_token + default_ca_cert = var.gitops_default_ca_cert + host = var.gitops_host + org = var.gitops_org + project = var.gitops_project + repo = var.gitops_repo + username = var.gitops_username + token = var.gitops_token + branch = var.gitops_branch + server_name = var.gitops_server_name + ca_cert = var.gitops_ca_cert + ca_cert_file = var.gitops_ca_cert_file +} +provider "clis" { + + + + } \ No newline at end of file diff --git a/1-quickstart/1-aro/220-dev-tools/terragrunt.hcl b/1-quickstart/1-aro/220-dev-tools/terragrunt.hcl index 94ccef4..b9e21c7 100644 --- a/1-quickstart/1-aro/220-dev-tools/terragrunt.hcl +++ b/1-quickstart/1-aro/220-dev-tools/terragrunt.hcl @@ -34,10 +34,10 @@ dependency "gitops" { } 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 + gitops_repo_host = dependency.gitops.outputs.gitops_repo_config_host + gitops_repo_org = dependency.gitops.outputs.gitops_repo_config_org + gitops_repo_repo = dependency.gitops.outputs.gitops_repo_config_name + gitops_repo_project = dependency.gitops.outputs.gitops_repo_config_project + gitops_repo_username = dependency.gitops.outputs.gitops_repo_config_username + gitops_repo_token = dependency.gitops.outputs.gitops_repo_config_token } \ No newline at end of file diff --git a/1-quickstart/1-aro/220-dev-tools/variables.tf b/1-quickstart/1-aro/220-dev-tools/variables.tf index 5a863ab..4bdf83a 100644 --- a/1-quickstart/1-aro/220-dev-tools/variables.tf +++ b/1-quickstart/1-aro/220-dev-tools/variables.tf @@ -23,6 +23,81 @@ variable "gitops-artifactory_persistence" { description = "Flag to indicate if persistence should be enabled" default = true } +variable "gitops_default_host" { + type = string + description = "the value of gitops_default_host" + default = "" +} +variable "gitops_default_org" { + type = string + description = "the value of gitops_default_org" + default = "" +} +variable "gitops_default_username" { + type = string + description = "the value of gitops_default_username" + default = "" +} +variable "gitops_default_token" { + type = string + description = "the value of gitops_default_token" + default = "" +} +variable "gitops_default_ca_cert" { + type = string + description = "the value of gitops_default_ca_cert" + default = "" +} +variable "gitops_host" { + type = string + description = "The host name of the gitops repository (GitHub, Github Enterprise, Gitlab, Bitbucket, Azure DevOps, and Gitea servers are supported)." + default = "" +} +variable "gitops_org" { + type = string + description = "The organization on the git server where the repsitory will be located. If not provided the org will default to the username." + default = "" +} +variable "gitops_project" { + type = string + description = "The Azure DevOps project in the git server. This value is only applied for Azure DevOps servers." + default = "" +} +variable "gitops_repo" { + type = string + description = "The name of the repository in the org on the git server." + default = "" +} +variable "gitops_username" { + type = string + description = "The username used to access the git server." + default = "" +} +variable "gitops_token" { + type = string + description = "The token used to access the git server." + default = "" +} +variable "gitops_branch" { + type = string + description = "The name of the branch in the gitops repository where the config will be stored." + default = "main" +} +variable "gitops_server_name" { + type = string + description = "The name of the server the configuration with which the configuration will be associated." + default = "default" +} +variable "gitops_ca_cert" { + type = string + description = "The ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" +} +variable "gitops_ca_cert_file" { + type = string + description = "The file containing the ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" +} variable "gitops-dashboard_cluster_type" { type = string description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" diff --git a/1-quickstart/1-aro/220-dev-tools/version.tf b/1-quickstart/1-aro/220-dev-tools/version.tf index 5034007..da8ce2a 100644 --- a/1-quickstart/1-aro/220-dev-tools/version.tf +++ b/1-quickstart/1-aro/220-dev-tools/version.tf @@ -2,6 +2,12 @@ terraform { required_providers { gitops = { source = "cloud-native-toolkit/gitops" + version = "0.11.1" + } + + clis = { + source = "cloud-native-toolkit/clis" + version = "0.2.4" } } diff --git a/1-quickstart/1-aro/README.md b/1-quickstart/1-aro/README.md index 25c1ff9..ea6d0c0 100644 --- a/1-quickstart/1-aro/README.md +++ b/1-quickstart/1-aro/README.md @@ -91,7 +91,11 @@ The automation is delivered in a number of layers that are applied in order. Lay 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. +3. 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.\ + +4. If using your Azure account, use the interactive approach in `launch.sh` to login to the Azure CLI. + +4. (Optional) If using a service principal instead of your Azure account, [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 @@ -105,11 +109,9 @@ The automation is delivered in a number of layers that are applied in order. Lay "tenant":"" ``` - 1. Give permissions to the service principal to create other service principals and the ARO cluster (refer [here](./sp-setup.md) for details) + 2. 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. +5. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. ```shell brew install docker colima @@ -124,19 +126,17 @@ The automation is delivered in a number of layers that are applied in order. Lay 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 + - **TF_VAR_subscription_id** - (Optional) The Azure subscription id where the cluster will be deployed + - **TF_VAR_tenant_id** - (Optional) The Azure tenant id that owns the subscription + - **TV_VAR_client_id** - (Optional) The id of the service principal with Owner and User Administrator access to the subscription for cluster creation + - **TV_VAR_client_secret** - (Optional) 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. +4. Run **./launch.sh**. This will start a container image and can walk through the setup. If you do not select to setup the workspace, continue to the next step, otherwise, you can build straight from the launch script. 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] @@ -147,7 +147,7 @@ The automation is delivered in a number of layers that are applied in order. Lay - **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 + $ 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. @@ -163,8 +163,8 @@ The automation is delivered in a number of layers that are applied in order. Lay From the **/workspace/current** directory, run the following: -``` -./apply-all.sh -a +```shell +$ ./apply-all.sh -a ``` The script will run through each of the terraform layers in sequence to provision the entire infrastructure. @@ -174,14 +174,13 @@ The script will run through each of the terraform layers in sequence to provisio From the **/workspace/current** directory, change directory into each of the layer subdirectories and run the following: ```shell -terragrunt init -terragrunt apply -auto-approve +$ 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 +```shell +$ /workspace/current/show-login.sh ``` diff --git a/1-quickstart/1-aro/launch.sh b/1-quickstart/1-aro/launch.sh index a54d5c5..1d9d282 100755 --- a/1-quickstart/1-aro/launch.sh +++ b/1-quickstart/1-aro/launch.sh @@ -7,7 +7,18 @@ SRC_DIR="${SCRIPT_DIR}/automation" AUTOMATION_BASE=$(basename "${SCRIPT_DIR}") -DOCKER_CMD="${1:-docker}" +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}" @@ -38,10 +49,10 @@ then fi -DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools:v1.2-v2.2.11" -#IBM DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-ibmcloud:v1.2-v0.4.15" -#AWS DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-aws:v1.2-v0.3.11" -#AZURE DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.4.11" +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}" @@ -51,9 +62,11 @@ 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 -if [[ -n "$1" ]]; then - echo "Pulling container image: ${DOCKER_IMAGE}" - ${DOCKER_CMD} pull "${DOCKER_IMAGE}" +ARG_ARRAY=( "$@" ) + +if [[ " ${ARG_ARRAY[*]} " =~ " --pull " ]]; then + echo "Pulling container image: ${DOCKER_IMAGE}" + ${DOCKER_CMD} pull "${DOCKER_IMAGE}" fi @@ -80,11 +93,10 @@ 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}:/workspaces" \ + -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/101-azure-vnet-std/bom.yaml b/2-standard/1-aro/101-azure-vnet-std/bom.yaml index 15d2274..384c260 100644 --- a/2-standard/1-aro/101-azure-vnet-std/bom.yaml +++ b/2-standard/1-aro/101-azure-vnet-std/bom.yaml @@ -24,7 +24,7 @@ spec: - 10.0.0.0/20 - name: azure-vnet-subnets alias: master_subnet - version: v1.3.9 + version: v1.3.10 default: true variables: - name: label @@ -42,7 +42,7 @@ spec: value: true - name: azure-vnet-subnets alias: worker_subnet - version: v1.3.9 + version: v1.3.10 variables: - name: label value: worker @@ -55,7 +55,7 @@ spec: - Microsoft.Storage - name: azure-vnet-subnets alias: ingress_subnet - version: v1.3.9 + version: v1.3.10 variables: - name: label value: ingress diff --git a/2-standard/1-aro/101-azure-vnet-std/dependencies.dot b/2-standard/1-aro/101-azure-vnet-std/dependencies.dot index ee52254..795300b 100644 --- a/2-standard/1-aro/101-azure-vnet-std/dependencies.dot +++ b/2-standard/1-aro/101-azure-vnet-std/dependencies.dot @@ -20,7 +20,7 @@ digraph { "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)" -> "ingress_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/docs/azure-vnet-subnets.md b/2-standard/1-aro/101-azure-vnet-std/docs/azure-vnet-subnets.md index e648a22..a09d0e8 100644 --- 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 @@ -19,11 +19,12 @@ The module depends on the following software components: #### Command-line tools -- terraform >= v0.15 +- terraform >= v0.15 and < v1.3 +***Note that this module does nto support terraform version 1.3 and above*** #### Terraform providers -- Azure provider +- Azure provider >= 3.27.0 ### Module dependencies @@ -83,6 +84,25 @@ module "subnets" { } ``` +## Read Only Usage + +The module may be utilised in a read-only mode by setting provision=false. + +Doing so will cause the module to attempt to read an existing subnet that it is provided. Provide the resource group name, region, vnet name and subnet name in such circumstances to return the subnet details. ***Note that this method requires a single subnet name at a time*** + +For example: +```hcl-terraform +module "subnet-query" { + source = "/home/richard/github/terraform-azure-subnets" + + provision = false + resource_group_name = module.resource_group.name + vnet_name = module.vnet.name + region = module.resource_group.region + subnet_name = "test-subnet" +} +``` + ## Input Variables This module has the following input variables: diff --git a/2-standard/1-aro/101-azure-vnet-std/main.tf b/2-standard/1-aro/101-azure-vnet-std/main.tf index 47a9ea4..f501f75 100644 --- a/2-standard/1-aro/101-azure-vnet-std/main.tf +++ b/2-standard/1-aro/101-azure-vnet-std/main.tf @@ -1,5 +1,5 @@ module "ingress_subnet" { - source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" 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 @@ -14,7 +14,7 @@ module "ingress_subnet" { vnet_name = module.vnet.name } module "master_subnet" { - source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" 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 @@ -62,6 +62,7 @@ module "ssh-keys" { 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 + tags = var.ssh-keys_tags } module "vnet" { source = "github.com/cloud-native-toolkit/terraform-azure-vnet?ref=v1.1.3" @@ -98,7 +99,7 @@ module "vpn-server" { vm_size = var.vpn-server_vm_size } module "worker_subnet" { - source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.9" + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" 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 diff --git a/2-standard/1-aro/101-azure-vnet-std/providers.tf b/2-standard/1-aro/101-azure-vnet-std/providers.tf index 978f99b..bac303b 100644 --- a/2-standard/1-aro/101-azure-vnet-std/providers.tf +++ b/2-standard/1-aro/101-azure-vnet-std/providers.tf @@ -1,7 +1,9 @@ provider "azurerm" { + features {} + subscription_id = var.subscription_id client_id = var.client_id client_secret = var.client_secret diff --git a/2-standard/1-aro/101-azure-vnet-std/variables.tf b/2-standard/1-aro/101-azure-vnet-std/variables.tf index 260d6b2..72cebcc 100644 --- a/2-standard/1-aro/101-azure-vnet-std/variables.tf +++ b/2-standard/1-aro/101-azure-vnet-std/variables.tf @@ -242,6 +242,11 @@ variable "ssh-keys_ecdsa_curve" { description = "ECDSA Curve value to be utilized for ECDSA key (P224, P256, P521, default = P224)" default = "P224" } +variable "ssh-keys_tags" { + type = map(string) + description = "Extra tags to be added to the Azure Vault entry (default = none)" + default = {} +} variable "vpn-server_private_network_cidrs" { type = string description = "List of CIDRs in the private network reachable via the VPN server." diff --git a/2-standard/1-aro/101-azure-vnet-std/version.tf b/2-standard/1-aro/101-azure-vnet-std/version.tf index eb2f15f..ee1686f 100644 --- a/2-standard/1-aro/101-azure-vnet-std/version.tf +++ b/2-standard/1-aro/101-azure-vnet-std/version.tf @@ -2,6 +2,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" + version = "3.32.0" } } 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 index e367246..d458c87 100644 --- 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 @@ -19,3 +19,9 @@ ## name_prefix: The name of the vpc resource #name_prefix="" +## pull_secret: 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 +#pull_secret="" + +## pull_secret_file: 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 +#pull_secret_file="" + diff --git a/2-standard/1-aro/105-azure-aro-std/bom.yaml b/2-standard/1-aro/105-azure-aro-std/bom.yaml index 6e064ba..1cacd8f 100644 --- a/2-standard/1-aro/105-azure-aro-std/bom.yaml +++ b/2-standard/1-aro/105-azure-aro-std/bom.yaml @@ -26,7 +26,7 @@ spec: value: false - name: azure-vnet-subnets alias: master-subnet - version: v1.3.9 + version: v1.3.10 variables: - name: label value: master @@ -34,7 +34,7 @@ spec: value: false - name: azure-vnet-subnets alias: worker-subnet - version: v1.3.9 + version: v1.3.10 variables: - name: label value: worker @@ -42,7 +42,7 @@ spec: value: false - name: azure-aro alias: cluster - version: v1.0.0 + version: v2.0.0 dependencies: - name: master-subnet ref: master-subnet @@ -53,6 +53,10 @@ spec: ref: master-subnet - name: worker_subnet_id ref: worker-subnet + - name: encrypt + value: true + - name: disable_public_endpoint + value: true variables: - name: resource_group_name type: string @@ -73,3 +77,17 @@ spec: type: string description: The name of the vpc resource defaultValue: '' + - name: 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 + defaultValue: '' + - name: 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 + defaultValue: '' 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 index 101f5c8..d404b2b 100644 --- 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 @@ -3,20 +3,29 @@ ## 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) +- terraform-util-clis - to setup CLI utils for build +- terraform-ocp-login - to login to the cluster once it is built +- random_domain - generates a random domain name +- null_resource az_login - to login to the az cli with the supplied credentials, or use existing login +- external aro_rp - to obtain OpenShift resource provider details +- null_resource service_principal - to create and destroy a service principal for cluster to use to call Azure API +- azurerm_key_vault - if a key_vault_id is not provided, this will create a new key vault for the service principal details +- azurerm_key_vault_secret - to store the service principal details +- azurerm_role_assignment - assigns required roles to service principal and resource provider +- azapi_resource - CRUD for the ARO cluster +- external aro - obtains details of the created cluster +- time_sleep - a delay to allow the cluster to settle ### Software dependencies -- terraform CLI >= 1.2.6 -- Azure CLI (az) >= 2.39.0 +- terraform CLI >= 1.2.6 +- Azure CLI (az) >= 2.42.0 (must be in the path environment variable) ### Terraform providers - Terraform >= 0.15.0 -- Azure provider >= 3.0.0 +- Azure provider (azurerm) >= 3.3.0 +- Azure API provider (azapi) >= 1.0.0 ### Module dependencies @@ -27,9 +36,17 @@ This module makes use of the output from other modules: ## Prerequisites -### Option 1 - Use a service principal +### Common -The service principal needs the following roles assigned +Ensure that the subscription has the `Microsoft.RedHatOpenShift` provider namespace registerd. +To do so: + ``` + $ az provider register --namespace "Microsoft.RedHatOpenShift" + ``` + +### Azure Login Option 1 - Use a service principal + +Use this option with automated execution. The service principal needs the following roles assigned - In the active directory, application and user administrator permissions - User Administrator @@ -68,9 +85,46 @@ The service principal needs the following roles assigned 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. +1. Export the service principal details are environment variables. + + ``` + $ export TF_VAR_subscription_id= + $ export TF_VAR_tenant_id= + $ export TF_VAR_client_id= + $ export TF_VAR_client_secret= + ``` + +1. Set the variables in the provider block to use those credentials + ```hcl-terraform + provider "azurerm" { + features {} + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id + } + ``` + +### Azure Login Option 2 - Use your Azure user id + +Use this option if running from your terminal. Uses your Azure user. +***Note that your Azure user must have contributor and user access administrator rights to the subscription*** +1. Login to the az cli from within the container before proceeding with terraform actions. + ``` + $ az login + ``` +1. If you have more than one subscription, set the relevant subscription to be used. + ``` + $ az account set --subscription="" + ``` + where is the id of the subscription to be utilized. + +1. Do not include the login details in the provider.tf file in terraform + ```hcl-terraform + provider "azurerm" { + features {} + } + ``` ## Example Usage @@ -119,17 +173,13 @@ 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 + worker_subnet_id = module.worker-subnet.id + + encrypt = true } ``` @@ -137,21 +187,15 @@ module "aro" { ### Inputs -### Inputs - This module has the following input variables: -| Variable | Mandatory / Optional | Default Value | Description | +| Variable | Default Value | Mandatory / Optional | 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 | +| resource_group_name | | Mandatory | The resource group of the network (VNet and subnet) components. A new resource group will be created for the cluster. The location of the cluster will be the same as this resource group. | | 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_prefix | | Mandatory | Name to prefix the created resources | +| client_secret | "" | Optional | The secret of the service principal to be used for the cluster creation and ongoing management. Provide if using a service principal for azurerm login. | | 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 | @@ -162,6 +206,12 @@ This module has the following input variables: | 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 | +| key_vault_id | "" | Optional | Existing key vault id to use (will create a new one if not provided) | +| encrypt | false | Optional | Flag to encrypt the master and worker nodes with server side encryption | +| pod_cidr | 10.128.0.0/14 | Optional | CIDR for the internal pod subnet | +| service_cidr | 172.30.0.0/16 | Optional | CIDR for the internal services subnet | +| fips | false | Optional | Flag to use FIPS validated modules | +| tags | {} | Optional | List of tags to be included as name value key pairs | ### Outputs @@ -177,4 +227,5 @@ The module outputs the following values: | username | The login username for the cluster | | password | The login password for the cluster | | serverURL | The API URL for the cluster | +| console_url | The URL of the web console 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-vnet-subnets.md b/2-standard/1-aro/105-azure-aro-std/docs/azure-vnet-subnets.md index e648a22..a09d0e8 100644 --- 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 @@ -19,11 +19,12 @@ The module depends on the following software components: #### Command-line tools -- terraform >= v0.15 +- terraform >= v0.15 and < v1.3 +***Note that this module does nto support terraform version 1.3 and above*** #### Terraform providers -- Azure provider +- Azure provider >= 3.27.0 ### Module dependencies @@ -83,6 +84,25 @@ module "subnets" { } ``` +## Read Only Usage + +The module may be utilised in a read-only mode by setting provision=false. + +Doing so will cause the module to attempt to read an existing subnet that it is provided. Provide the resource group name, region, vnet name and subnet name in such circumstances to return the subnet details. ***Note that this method requires a single subnet name at a time*** + +For example: +```hcl-terraform +module "subnet-query" { + source = "/home/richard/github/terraform-azure-subnets" + + provision = false + resource_group_name = module.resource_group.name + vnet_name = module.vnet.name + region = module.resource_group.region + subnet_name = "test-subnet" +} +``` + ## Input Variables This module has the following input variables: diff --git a/2-standard/1-aro/105-azure-aro-std/main.tf b/2-standard/1-aro/105-azure-aro-std/main.tf index 49d4ea7..d437f16 100644 --- a/2-standard/1-aro/105-azure-aro-std/main.tf +++ b/2-standard/1-aro/105-azure-aro-std/main.tf @@ -1,3 +1,45 @@ +module "cluster" { + source = "github.com/cloud-native-toolkit/terraform-azure-aro?ref=v2.0.0" + + client_secret = var.client_secret + disable_public_endpoint = var.cluster_disable_public_endpoint + encrypt = var.cluster_encrypt + fips = var.cluster_fips + key_vault_id = var.cluster_key_vault_id + label = var.cluster_label + master_flavor = var.cluster_master_flavor + master_subnet_id = module.master-subnet.id + name = var.cluster_name + name_prefix = var.name_prefix + os_type = var.cluster_os_type + pod_cidr = var.cluster_pod_cidr + provision = var.cluster_provision + pull_secret = var.pull_secret + pull_secret_file = var.pull_secret_file + resource_group_name = module.resource_group.name + service_cidr = var.cluster_service_cidr + tags = var.cluster_tags + vnet_name = module.vnet.name + worker_count = var.cluster_worker_count + worker_disk_size = var.cluster_worker_disk_size + worker_flavor = var.cluster_worker_flavor + worker_subnet_id = module.worker-subnet.id +} +module "master-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" + + 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 "resource_group" { source = "github.com/cloud-native-toolkit/terraform-azure-resource-group?ref=v1.1.1" @@ -19,30 +61,18 @@ module "vnet" { region = var.region resource_group_name = module.resource_group.name } +module "worker-subnet" { + source = "github.com/cloud-native-toolkit/terraform-azure-subnets?ref=v1.3.10" -// 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 + 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 - 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 + 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/105-azure-aro-std/output.tf b/2-standard/1-aro/105-azure-aro-std/output.tf index 7423b09..eea3b0f 100644 --- a/2-standard/1-aro/105-azure-aro-std/output.tf +++ b/2-standard/1-aro/105-azure-aro-std/output.tf @@ -1,4 +1,135 @@ - +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 "cluster_id" { description = "ID of the created cluster" value = module.cluster.id @@ -22,6 +153,11 @@ output "cluster_config_file_path" { output "cluster_token" { description = "Login token for the cluster" value = module.cluster.token + sensitive = true +} +output "cluster_console_url" { + description = "The URL for the web console of the cluster" + value = module.cluster.console_url } output "cluster_username" { description = "Username for the cluster" @@ -45,7 +181,3 @@ 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 index 978f99b..bac303b 100644 --- a/2-standard/1-aro/105-azure-aro-std/providers.tf +++ b/2-standard/1-aro/105-azure-aro-std/providers.tf @@ -1,7 +1,9 @@ provider "azurerm" { + features {} + subscription_id = var.subscription_id client_id = var.client_id client_secret = var.client_secret diff --git a/2-standard/1-aro/105-azure-aro-std/variables.tf b/2-standard/1-aro/105-azure-aro-std/variables.tf index ed3fd1d..590cddb 100644 --- a/2-standard/1-aro/105-azure-aro-std/variables.tf +++ b/2-standard/1-aro/105-azure-aro-std/variables.tf @@ -1,18 +1,3 @@ -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" @@ -34,18 +19,22 @@ variable "region" { variable "subscription_id" { type = string description = "the value of subscription_id" + default = null } variable "client_id" { type = string description = "the value of client_id" + default = null } variable "client_secret" { type = string description = "the value of client_secret" + default = null } variable "tenant_id" { type = string description = "the value of tenant_id" + default = null } variable "vnet_name" { type = string @@ -161,22 +150,17 @@ variable "worker-subnet_disable_private_link_service_network_policies" { 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" { +variable "cluster_worker_flavor" { type = string description = "The size of the VMs for the worker nodes" default = "Standard_D4s_v3" } -variable "cluster__count" { +variable "cluster_worker_count" { type = number description = "The number of compute worker nodes" default = 3 @@ -196,22 +180,22 @@ variable "cluster_name" { 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 + default = true } -variable "cluster_disk_size" { +variable "cluster_worker_disk_size" { type = number description = "The size in GB of the disk for each worker node" default = 128 } -variable "cluster_pull_secret_file" { +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 "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 = "" @@ -221,3 +205,33 @@ variable "cluster_label" { description = "The label used to generate the cluster name" default = "cluster" } +variable "cluster_key_vault_id" { + type = string + description = "THe Azure id of an existing key vault to use to store ARO Service Principal credentials (default = \"\")" + default = "" +} +variable "cluster_encrypt" { + type = bool + description = "Flag to encrypt the VM disks (default = false)" + default = true +} +variable "cluster_pod_cidr" { + type = string + description = "CIDR for the POD subnet (default = \"10.128.0.0/14\")" + default = "10.128.0.0/14" +} +variable "cluster_service_cidr" { + type = string + description = "CIDR for the services subnet (default = \"172.30.0.0/16\")" + default = "172.30.0.0/16" +} +variable "cluster_fips" { + type = bool + description = "Flag to determine if FIPS validated modules should be utilized (default = false)" + default = false +} +variable "cluster_tags" { + type = map(string) + description = "List of tags to be included as \"name\":\"value\" pairs (default = {})" + default = {} +} diff --git a/2-standard/1-aro/105-azure-aro-std/version.tf b/2-standard/1-aro/105-azure-aro-std/version.tf index eb2f15f..ee1686f 100644 --- a/2-standard/1-aro/105-azure-aro-std/version.tf +++ b/2-standard/1-aro/105-azure-aro-std/version.tf @@ -2,6 +2,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" + version = "3.32.0" } } 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 index c46b96f..5f3aa26 100644 --- 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 @@ -1,12 +1,6 @@ ## 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="" @@ -25,3 +19,9 @@ ## gitops_repo_repo: The short name of the repository (i.e. the part after the org/group name) #gitops_repo_repo="" +## 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/200-openshift-gitops/apply.sh b/2-standard/1-aro/200-openshift-gitops/apply.sh index e64c76a..cc88204 100755 --- a/2-standard/1-aro/200-openshift-gitops/apply.sh +++ b/2-standard/1-aro/200-openshift-gitops/apply.sh @@ -4,7 +4,7 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) VARIABLES_FILE="${1}" if [[ -z "${VARIABLES_FILE}" ]]; then - VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" + VARIABLES_FILE="variables.yaml" fi YQ=$(command -v yq4 || command -v yq) @@ -13,11 +13,25 @@ if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g" 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" +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 "" @@ -27,17 +41,18 @@ 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 // ""' -) +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" - variable_name="TF_VAR_${name}" + 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 '.variables[] | select(.name == env(NAME)) | .value // ""' -) + 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 @@ -60,15 +75,44 @@ cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while rea value=${value:-$default_value} done - echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + 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}" -cd ${SCRIPT_DIR}/terraform +source credentials.properties + +cd 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 index d77ae60..bec29b4 100644 --- a/2-standard/1-aro/200-openshift-gitops/bom.yaml +++ b/2-standard/1-aro/200-openshift-gitops/bom.yaml @@ -13,15 +13,9 @@ metadata: 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 + version: v3.2.4 variables: - name: name value: gitea @@ -31,15 +25,9 @@ spec: 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-cluster-config + alias: config + version: v1.1.1 - name: gitops-console-link-job alias: gitops-console-link-job version: v1.5.1 @@ -50,23 +38,28 @@ spec: variables: - name: name value: toolkit - - name: util-clis - version: v1.17.2 + - name: gitops-repo + alias: gitops_repo + version: v1.23.1 + - name: argocd-bootstrap + alias: argocd-bootstrap + version: v1.12.0 + variables: + - name: create_webhook + value: true + - name: ocp-login + alias: cluster + version: v1.6.0 - name: olm - version: v1.3.2 + version: v1.3.5 + - name: util-clis + version: v1.18.1 - 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: >- @@ -100,3 +93,10 @@ spec: description: >- The short name of the repository (i.e. the part after the org/group name) + - 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/200-openshift-gitops/dependencies.dot b/2-standard/1-aro/200-openshift-gitops/dependencies.dot index 89b4ec2..0c7d29d 100644 --- a/2-standard/1-aro/200-openshift-gitops/dependencies.dot +++ b/2-standard/1-aro/200-openshift-gitops/dependencies.dot @@ -1,30 +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_namespace (namespace)" -> "cluster (ocp-login)" +"gitea_namespace (namespace)" +"cluster (ocp-login)" "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)" +"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)" "toolkit_namespace (gitops-namespace)" -> "gitops_repo (gitops-repo)" "toolkit_namespace (gitops-namespace)" +"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)" "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/docs/gitops-cluster-config.md b/2-standard/1-aro/200-openshift-gitops/docs/gitops-cluster-config.md index 8079c97..3014600 100644 --- 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 @@ -1,39 +1,66 @@ -# Cluster config gitops module +# Cluster Config module + +Module to populate a gitops repository with base configuration of the Red Hat OpenShift cluster (notification banner, help menus, etc) -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 version -- terraform - v14 -- kubectl +- \>= v0.15 ### Terraform providers -None -## Module dependencies +- gitops (cloud-native-toolkit/gitops) -This module makes use of the output from other modules: +### Module dependencies -- Gitops - github.com/cloud-native-toolkit/terraform-tools-gitops.git -- Namespace - github.com/cloud-native-toolkit/terraform-gitops-namespace.git + +- gitops - [github.com/cloud-native-toolkit/terraform-tools-gitops.git](https://github.com/cloud-native-toolkit/terraform-tools-gitops.git) (>= 1.1.0) +- namespace - [github.com/cloud-native-toolkit/terraform-gitops-namespace.git](https://github.com/cloud-native-toolkit/terraform-gitops-namespace.git) (>= 1.0.0) ## Example usage -```hcl-terraform -module "cluster-config" { - source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config.git" +```hcl +module "gitops-cluster-config" { + source = "github.com/cloud-native-toolkit/terraform-gitops-cluster-config" - 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 + banner_background_color = var.gitops-cluster-config_banner_background_color + banner_text = var.gitops-cluster-config_banner_text + banner_text_color = var.gitops-cluster-config_banner_text_color + git_credentials = module.gitops_repo.git_credentials + gitops_config = module.gitops_repo.gitops_config + namespace = module.namespace.name + server_name = module.gitops_repo.server_name } + ``` +## Module details + +### Inputs + +| Name | Description | Required | Default | Source | +|------|-------------|---------|----------|--------| +| gitops_config | Config information regarding the gitops repo structure | true | | gitops.gitops_config | +| git_credentials | The credentials for the gitops repo(s) | true | | gitops.git_credentials | +| namespace | The namespace where the application should be deployed | true | | namespace.name | +| server_name | The name of the server | false | default | gitops.server_name | +| banner_background_color | The background color of the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000). | false | purple | | +| banner_text_color | The text color for the top banner. This value can be a named color (e.g. purple, red) or an RGB value (#FF0000). | false | white | | +| banner_text | The text that will appear in the top banner in the cluster | true | | | + +### Outputs + + +None + +## Resources + +- [Documentation](https://operate.cloudnativetoolkit.dev) +- [Module catalog](https://modules.cloudnativetoolkit.dev) + +> License: Apache License 2.0 | Generated by iascable (3.0.0-beta.10) diff --git a/2-standard/1-aro/200-openshift-gitops/docs/olm.md b/2-standard/1-aro/200-openshift-gitops/docs/olm.md index 4616b71..85fe38a 100644 --- a/2-standard/1-aro/200-openshift-gitops/docs/olm.md +++ b/2-standard/1-aro/200-openshift-gitops/docs/olm.md @@ -1,29 +1,66 @@ + # 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. +Installs Operator Lifecycle Manager in the cluster + +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. + + +## Software dependencies + +The module depends on the following software components: + +### Terraform version + +- \>= v0.15 + +### Terraform providers + +- clis (cloud-native-toolkit/clis) + +### Module dependencies + +- cluster - interface github.com/cloud-native-toolkit/automation-modules#cluster ## 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" +[Refer to examples for more details](test/stages) - cluster_config_file = "~/.kube/config" - cluster_version = "3.11" - cluster_type = "ocp3" +``` +module "olm" { + source = "github.com/cloud-native-toolkit/terraform-k8s-olm" + + cluster_config_file = module.cluster.config_file_path + cluster_type = module.cluster.platform.type_code + cluster_version = module.cluster.platform.version } ``` -Another example +## Module details -```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" +### Inputs - cluster_config_file = module.dev_cluster.config_file_path - cluster_version = module.dev_cluster.version - cluster_type = var.cluster_type -} -``` +| Name | Description | Required | Default | Source | +|------|-------------|---------|----------|--------| +| cluster_type | The type of cluster (openshift or kubernetes) | true | | cluster.platform.type_code | +| cluster_version | The version of cluster | true | | cluster.platform.version | +| cluster_config_file | Cluster config file for Kubernetes cluster. | true | | cluster.config_file_path | +| olm_version | The version of olm that will be installed | | v0.18.1 | | + + +### Outputs + +| Name | Description | +|------|-------------| +| olm_namespace | Namespace where OLM is running. The value will be different between OCP 4.3 and IKS/OCP 3.11 | +| target_namespace | Namespace where operatoes will be installed | +| operator_namespace | Name space where catalog is running - and subscriptions need to be made | + + +## Resources + +- [Documentation](https://operate.cloudnativetoolkit.dev) +- [Module catalog](https://modules.cloudnativetoolkit.dev) + +> License: Apache License 2.0 | Generated by iascable (2.25.5) diff --git a/2-standard/1-aro/200-openshift-gitops/main.tf b/2-standard/1-aro/200-openshift-gitops/main.tf index 94704e7..30556d2 100644 --- a/2-standard/1-aro/200-openshift-gitops/main.tf +++ b/2-standard/1-aro/200-openshift-gitops/main.tf @@ -55,14 +55,14 @@ module "gitea" { username = var.gitea_username } module "gitea_namespace" { - source = "github.com/cloud-native-toolkit/terraform-k8s-namespace?ref=v3.2.3" + source = "github.com/cloud-native-toolkit/terraform-k8s-namespace?ref=v3.2.4" 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" + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.23.1" branch = var.gitops_repo_branch debug = var.debug @@ -95,7 +95,7 @@ module "gitops-console-link-job" { 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" + source = "github.com/cloud-native-toolkit/terraform-k8s-olm?ref=v1.3.5" cluster_config_file = module.cluster.config_file_path cluster_type = module.cluster.platform.type_code @@ -122,7 +122,7 @@ module "toolkit_namespace" { } module "util-clis" { source = "cloud-native-toolkit/clis/util" - version = "1.17.2" + version = "1.18.1" 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/output.tf b/2-standard/1-aro/200-openshift-gitops/output.tf new file mode 100644 index 0000000..69863ff --- /dev/null +++ b/2-standard/1-aro/200-openshift-gitops/output.tf @@ -0,0 +1,248 @@ +output "gitea_namespace_name" { + description = "Namespace name" + value = module.gitea_namespace.name +} +output "gitea_namespace" { + description = "The namespace where the Gitea instance has been provisioned" + value = module.gitea.namespace +} +output "gitea_username" { + description = "The username of the Gitea admin user" + value = module.gitea.username +} +output "gitea_password" { + description = "The password of the Gitea admin user" + value = module.gitea.password + sensitive = true +} +output "gitea_token" { + description = "The api token of the Gitea admin user" + value = module.gitea.token + sensitive = true +} +output "gitea_host" { + description = "The host name of the gitea server" + value = module.gitea.host +} +output "gitea_org" { + description = "The host name of the gitea server" + value = module.gitea.org +} +output "gitea_ingress_host" { + description = "The host name of the gitea server" + value = module.gitea.ingress_host +} +output "gitea_ingress_url" { + description = "The url of the gitea server" + value = module.gitea.ingress_url +} +output "gitea_ca_cert" { + description = "Base64 encoded CA certificate for cluster endpoints" + value = module.gitea.ca_cert +} +output "gitops-console-link-job_name" { + description = "The name of the module" + value = module.gitops-console-link-job.name +} +output "gitops-console-link-job_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-console-link-job.branch +} +output "gitops-console-link-job_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-console-link-job.namespace +} +output "gitops-console-link-job_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-console-link-job.server_name +} +output "gitops-console-link-job_layer" { + description = "The layer where the module is deployed" + value = module.gitops-console-link-job.layer +} +output "gitops-console-link-job_type" { + description = "The type of module where the module is deployed" + value = module.gitops-console-link-job.type +} +output "toolkit_namespace_name" { + description = "Namespace name" + value = module.toolkit_namespace.name +} +output "gitops_repo_config_host" { + description = "The host name of the bootstrap git repo" + value = module.gitops_repo.config_host +} +output "gitops_repo_config_org" { + description = "The org name of the bootstrap git repo" + value = module.gitops_repo.config_org +} +output "gitops_repo_config_name" { + description = "The repo name of the bootstrap git repo" + value = module.gitops_repo.config_name +} +output "gitops_repo_config_project" { + description = "The project name of the bootstrap git repo (for Azure DevOps)" + value = module.gitops_repo.config_project +} +output "gitops_repo_config_repo" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo +} +output "gitops_repo_config_repo_url" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo_url +} +output "gitops_repo_config_ca_cert" { + description = "The ca cert for the self-signed certificate used by the gitops repo" + value = module.gitops_repo.config_ca_cert +} +output "gitops_repo_config_username" { + description = "The username for the config repo" + value = module.gitops_repo.config_username +} +output "gitops_repo_config_token" { + description = "The token for the config repo" + value = module.gitops_repo.config_token + sensitive = true +} +output "gitops_repo_config_paths" { + description = "The paths in the config repo" + value = module.gitops_repo.config_paths +} +output "gitops_repo_config_projects" { + description = "The ArgoCD projects for the different layers of the repo" + value = module.gitops_repo.config_projects +} +output "gitops_repo_bootstrap_path" { + description = "The path to the bootstrap configuration" + value = module.gitops_repo.bootstrap_path +} +output "gitops_repo_bootstrap_branch" { + description = "The branch in the gitrepo containing the bootstrap configuration" + value = module.gitops_repo.bootstrap_branch +} +output "gitops_repo_application_repo" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo +} +output "gitops_repo_application_repo_url" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo_url +} +output "gitops_repo_application_username" { + description = "The username for the application repo" + value = module.gitops_repo.application_username +} +output "gitops_repo_application_token" { + description = "The token for the application repo" + value = module.gitops_repo.application_token + sensitive = true +} +output "gitops_repo_application_paths" { + description = "The paths in the application repo" + value = module.gitops_repo.application_paths +} +output "gitops_repo_gitops_config" { + description = "Config information regarding the gitops repo structure" + value = module.gitops_repo.gitops_config +} +output "gitops_repo_git_credentials" { + description = "The credentials for the gitops repo(s)" + value = module.gitops_repo.git_credentials + sensitive = true +} +output "gitops_repo_server_name" { + description = "The name of the cluster that will be configured for gitops" + value = module.gitops_repo.server_name +} +output "gitops_repo_sealed_secrets_cert" { + description = "The certificate used to encrypt sealed secrets" + value = module.gitops_repo.sealed_secrets_cert +} +output "argocd-bootstrap_argocd_namespace" { + description = "The namespace where the ArgoCD instance has been provisioned" + value = module.argocd-bootstrap.argocd_namespace +} +output "argocd-bootstrap_argocd_service_account" { + description = "The namespace where the ArgoCD instance has been provisioned" + value = module.argocd-bootstrap.argocd_service_account +} +output "argocd-bootstrap_sealed_secrets_cert" { + description = "the value of argocd-bootstrap_sealed_secrets_cert" + value = module.argocd-bootstrap.sealed_secrets_cert +} +output "cluster_id" { + description = "ID of the cluster." + value = module.cluster.id +} +output "cluster_ocp_id" { + description = "OpenShift ID of the cluster." + value = module.cluster.ocp_id +} +output "cluster_name" { + description = "Name of the cluster" + value = module.cluster.name +} +output "cluster_region" { + description = "Region of the cluster" + value = module.cluster.region +} +output "cluster_resource_group_name" { + description = "Resource group of the cluster" + value = module.cluster.resource_group_name +} +output "cluster_server_url" { + description = "The url of the control server." + value = module.cluster.server_url +} +output "cluster_username" { + description = "The username of the control server." + value = module.cluster.username +} +output "cluster_password" { + description = "The password of the control server." + value = module.cluster.password + sensitive = true +} +output "cluster_token" { + description = "The token of the control server." + value = module.cluster.token + sensitive = true +} +output "cluster_config_file_path" { + description = "Path to the config file for the cluster." + value = module.cluster.config_file_path +} +output "cluster_platform" { + description = "Configuration values for the cluster platform" + value = module.cluster.platform +} +output "cluster_ca_cert" { + description = "Base64 encoded CA certificate for cluster endpoints" + value = module.cluster.ca_cert +} +output "olm_olm_namespace" { + description = "Namespace where OLM is running. The value will be different between OCP 4.3 and IKS/OCP 3.11" + value = module.olm.olm_namespace +} +output "olm_target_namespace" { + description = "Namespace where operatoes will be installed" + value = module.olm.target_namespace +} +output "olm_operator_namespace" { + description = "Name space where catalog is running - and subscriptions need to be made" + value = module.olm.operator_namespace +} +output "util-clis_bin_dir" { + description = "Directory where the clis were downloaded" + value = module.util-clis.bin_dir +} +output "sealed-secret-cert_private_key" { + description = "the value of sealed-secret-cert_private_key" + value = module.sealed-secret-cert.private_key + sensitive = true +} +output "sealed-secret-cert_cert" { + description = "the value of sealed-secret-cert_cert" + value = module.sealed-secret-cert.cert +} diff --git a/2-standard/1-aro/200-openshift-gitops/outputs.tf b/2-standard/1-aro/200-openshift-gitops/outputs.tf deleted file mode 100644 index eba03b0..0000000 --- a/2-standard/1-aro/200-openshift-gitops/outputs.tf +++ /dev/null @@ -1,19 +0,0 @@ -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 index 459ee95..f3c6350 100644 --- a/2-standard/1-aro/200-openshift-gitops/providers.tf +++ b/2-standard/1-aro/200-openshift-gitops/providers.tf @@ -2,5 +2,28 @@ provider "gitops" { + + bin_dir = module.util-clis.bin_dir + default_host = module.gitea.host + default_org = module.gitea.org + default_username = module.gitea.username + default_token = module.gitea.token + default_ca_cert = module.gitea.ca_cert + host = var.gitops_host + org = var.gitops_org + project = var.gitops_project + repo = var.gitops_repo + username = var.gitops_username + token = var.gitops_token + branch = var.gitops_branch + server_name = var.gitops_server_name + ca_cert = var.gitops_ca_cert + ca_cert_file = var.gitops_ca_cert_file +} +provider "clis" { + + + + } \ No newline at end of file diff --git a/2-standard/1-aro/200-openshift-gitops/variables.tf b/2-standard/1-aro/200-openshift-gitops/variables.tf index 835717f..cc8043d 100644 --- a/2-standard/1-aro/200-openshift-gitops/variables.tf +++ b/2-standard/1-aro/200-openshift-gitops/variables.tf @@ -1,3 +1,33 @@ +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 "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)." @@ -12,83 +42,90 @@ variable "config_banner_text" { type = string description = "The text that will appear in the top banner in the cluster" } -variable "server_url" { +variable "gitops_host" { type = string - description = "The url for the OpenShift api" + description = "The host name of the gitops repository (GitHub, Github Enterprise, Gitlab, Bitbucket, Azure DevOps, and Gitea servers are supported)." + default = "" } -variable "cluster_login_user" { +variable "gitops_org" { type = string - description = "Username for login" + description = "The organization on the git server where the repsitory will be located. If not provided the org will default to the username." default = "" } -variable "cluster_login_password" { +variable "gitops_project" { type = string - description = "Password for login" + description = "The Azure DevOps project in the git server. This value is only applied for Azure DevOps servers." default = "" } -variable "cluster_login_token" { +variable "gitops_repo" { 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 + description = "The name of the repository in the org on the git server." + default = "" } -variable "cluster_cluster_version" { +variable "gitops_username" { type = string - description = "[Deprecated] The version of the cluster (passed through to the output)" + description = "The username used to access the git server." default = "" } -variable "cluster_ingress_subdomain" { +variable "gitops_token" { type = string - description = "[Deprecated] The ingress subdomain of the cluster (passed through to the output)" + description = "The token used to access the git server." default = "" } -variable "cluster_tls_secret_name" { +variable "gitops_branch" { type = string - description = "[Deprecated] The name of the secret containing the tls certificates for the ingress subdomain (passed through to the output)" - default = "" + description = "The name of the branch in the gitops repository where the config will be stored." + default = "main" } -variable "cluster_ca_cert" { +variable "gitops_server_name" { type = string - description = "The base64 encoded ca certificate" - default = "" + description = "The name of the server the configuration with which the configuration will be associated." + default = "default" } -variable "cluster_ca_cert_file" { +variable "gitops_ca_cert" { type = string - description = "The path to the file that contains the ca certificate" + description = "The ca certificate used to sign the self-signed certificate used by the git server, if applicable." default = "" } -variable "gitea_namespace_name" { +variable "gitops_ca_cert_file" { 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 + description = "The file containing the ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" } -variable "gitea_instance_name" { +variable "gitops-console-link-job_cluster_ingress_hostname" { type = string - description = "The name for the instance" - default = "gitea" + description = "Ingress hostname of the IKS cluster." + default = "" } -variable "gitea_username" { +variable "gitops-console-link-job_cluster_type" { type = string - description = "The username for the instance" - default = "gitea-admin" + description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" + default = "ocp4" } -variable "gitea_password" { +variable "gitops-console-link-job_tls_secret_name" { type = string - description = "The password for the instance" + description = "The name of the secret containing the tls certificate values" default = "" } -variable "gitea_ca_cert_file" { +variable "toolkit_namespace_name" { type = string - description = "The path to the file that contains the ca certificate" - default = "" + 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 "gitops_repo_host" { type = string @@ -164,40 +201,53 @@ variable "argocd-bootstrap_create_webhook" { 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" { +variable "server_url" { type = string - description = "Ingress hostname of the IKS cluster." - default = "" + description = "The url for the OpenShift api" } -variable "gitops-console-link-job_cluster_type" { +variable "cluster_login_user" { type = string - description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" - default = "ocp4" + description = "Username for login" + default = "" } -variable "gitops-console-link-job_tls_secret_name" { +variable "cluster_login_password" { type = string - description = "The name of the secret containing the tls certificate values" + description = "Password for login" default = "" } -variable "toolkit_namespace_name" { +variable "cluster_login_token" { type = string - description = "The value that should be used for the namespace" - default = "toolkit" + description = "Token used for authentication" } -variable "toolkit_namespace_ci" { +variable "cluster_skip" { type = bool - description = "Flag indicating that this namespace will be used for development (e.g. configmaps and secrets)" + description = "Flag indicating that the cluster login has already been performed" 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 "cluster_cluster_version" { + type = string + description = "[Deprecated] The version of the cluster (passed through to the output)" + default = "" } -variable "toolkit_namespace_argocd_namespace" { +variable "cluster_ingress_subdomain" { type = string - description = "The namespace where argocd has been deployed" - default = "openshift-gitops" + 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 "util-clis_bin_dir" { type = string diff --git a/2-standard/1-aro/200-openshift-gitops/version.tf b/2-standard/1-aro/200-openshift-gitops/version.tf index 5034007..da8ce2a 100644 --- a/2-standard/1-aro/200-openshift-gitops/version.tf +++ b/2-standard/1-aro/200-openshift-gitops/version.tf @@ -2,6 +2,12 @@ terraform { required_providers { gitops = { source = "cloud-native-toolkit/gitops" + version = "0.11.1" + } + + clis = { + source = "cloud-native-toolkit/clis" + version = "0.2.4" } } diff --git a/2-standard/1-aro/220-dev-tools/apply.sh b/2-standard/1-aro/220-dev-tools/apply.sh index e64c76a..cc88204 100755 --- a/2-standard/1-aro/220-dev-tools/apply.sh +++ b/2-standard/1-aro/220-dev-tools/apply.sh @@ -4,7 +4,7 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) VARIABLES_FILE="${1}" if [[ -z "${VARIABLES_FILE}" ]]; then - VARIABLES_FILE="${SCRIPT_DIR}/variables.yaml" + VARIABLES_FILE="variables.yaml" fi YQ=$(command -v yq4 || command -v yq) @@ -13,11 +13,25 @@ if [[ -z "${YQ}" ]] || [[ $(${YQ} --version | sed -E "s/.*version ([34]).*/\1/g" 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" +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 "" @@ -27,17 +41,18 @@ 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 // ""' -) +function process_variable () { + local name="$1" + local default_value="$2" + local sensitive="$3" + local description="$4" - variable_name="TF_VAR_${name}" + 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 '.variables[] | select(.name == env(NAME)) | .value // ""' -) + 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 @@ -60,15 +75,44 @@ cat "${SCRIPT_DIR}/bom.yaml" | ${YQ} e '.spec.variables[] | .name' - | while rea value=${value:-$default_value} done - echo "${name} = \"${value}\"" >> "${SCRIPT_DIR}/terraform/terraform.tfvars" + 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}" -cd ${SCRIPT_DIR}/terraform +source credentials.properties + +cd 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 index 3709901..f337212 100644 --- a/2-standard/1-aro/220-dev-tools/bom.yaml +++ b/2-standard/1-aro/220-dev-tools/bom.yaml @@ -30,7 +30,7 @@ spec: version: v1.2.0 - name: gitops-repo alias: gitops_repo - version: v1.22.1 + version: v1.23.1 - name: gitops-sonarqube alias: gitops-sonarqube version: v1.3.0 @@ -41,7 +41,7 @@ spec: alias: gitops-tekton-resources version: v2.1.0 - name: util-clis - version: v1.17.2 + version: v1.18.1 - name: gitops-buildah-unprivileged version: v1.1.1 variables: diff --git a/2-standard/1-aro/220-dev-tools/main.tf b/2-standard/1-aro/220-dev-tools/main.tf index 31eeed2..40d8095 100644 --- a/2-standard/1-aro/220-dev-tools/main.tf +++ b/2-standard/1-aro/220-dev-tools/main.tf @@ -1,5 +1,5 @@ module "gitops_repo" { - source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.22.1" + source = "github.com/cloud-native-toolkit/terraform-tools-gitops?ref=v1.23.1" branch = var.gitops_repo_branch debug = var.debug @@ -117,7 +117,7 @@ module "tools_namespace" { } module "util-clis" { source = "cloud-native-toolkit/clis/util" - version = "1.17.2" + version = "1.18.1" 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/output.tf b/2-standard/1-aro/220-dev-tools/output.tf new file mode 100644 index 0000000..ab4853b --- /dev/null +++ b/2-standard/1-aro/220-dev-tools/output.tf @@ -0,0 +1,271 @@ +output "gitops-artifactory_name" { + description = "The name of the module" + value = module.gitops-artifactory.name +} +output "gitops-artifactory_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-artifactory.branch +} +output "gitops-artifactory_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-artifactory.namespace +} +output "gitops-artifactory_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-artifactory.server_name +} +output "gitops-artifactory_layer" { + description = "The layer where the module is deployed" + value = module.gitops-artifactory.layer +} +output "gitops-artifactory_type" { + description = "The type of module where the module is deployed" + value = module.gitops-artifactory.type +} +output "gitops-dashboard_name" { + description = "The name of the module" + value = module.gitops-dashboard.name +} +output "gitops-dashboard_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-dashboard.branch +} +output "gitops-dashboard_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-dashboard.namespace +} +output "gitops-dashboard_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-dashboard.server_name +} +output "gitops-dashboard_layer" { + description = "The layer where the module is deployed" + value = module.gitops-dashboard.layer +} +output "gitops-dashboard_type" { + description = "The type of module where the module is deployed" + value = module.gitops-dashboard.type +} +output "tools_namespace_name" { + description = "Namespace name" + value = module.tools_namespace.name +} +output "gitops-pact-broker_name" { + description = "The name of the module" + value = module.gitops-pact-broker.name +} +output "gitops-pact-broker_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-pact-broker.branch +} +output "gitops-pact-broker_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-pact-broker.namespace +} +output "gitops-pact-broker_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-pact-broker.server_name +} +output "gitops-pact-broker_layer" { + description = "The layer where the module is deployed" + value = module.gitops-pact-broker.layer +} +output "gitops-pact-broker_type" { + description = "The type of module where the module is deployed" + value = module.gitops-pact-broker.type +} +output "gitops_repo_config_host" { + description = "The host name of the bootstrap git repo" + value = module.gitops_repo.config_host +} +output "gitops_repo_config_org" { + description = "The org name of the bootstrap git repo" + value = module.gitops_repo.config_org +} +output "gitops_repo_config_name" { + description = "The repo name of the bootstrap git repo" + value = module.gitops_repo.config_name +} +output "gitops_repo_config_project" { + description = "The project name of the bootstrap git repo (for Azure DevOps)" + value = module.gitops_repo.config_project +} +output "gitops_repo_config_repo" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo +} +output "gitops_repo_config_repo_url" { + description = "The repo that contains the argocd configuration" + value = module.gitops_repo.config_repo_url +} +output "gitops_repo_config_ca_cert" { + description = "The ca cert for the self-signed certificate used by the gitops repo" + value = module.gitops_repo.config_ca_cert +} +output "gitops_repo_config_username" { + description = "The username for the config repo" + value = module.gitops_repo.config_username +} +output "gitops_repo_config_token" { + description = "The token for the config repo" + value = module.gitops_repo.config_token + sensitive = true +} +output "gitops_repo_config_paths" { + description = "The paths in the config repo" + value = module.gitops_repo.config_paths +} +output "gitops_repo_config_projects" { + description = "The ArgoCD projects for the different layers of the repo" + value = module.gitops_repo.config_projects +} +output "gitops_repo_bootstrap_path" { + description = "The path to the bootstrap configuration" + value = module.gitops_repo.bootstrap_path +} +output "gitops_repo_bootstrap_branch" { + description = "The branch in the gitrepo containing the bootstrap configuration" + value = module.gitops_repo.bootstrap_branch +} +output "gitops_repo_application_repo" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo +} +output "gitops_repo_application_repo_url" { + description = "The repo that contains the application configuration" + value = module.gitops_repo.application_repo_url +} +output "gitops_repo_application_username" { + description = "The username for the application repo" + value = module.gitops_repo.application_username +} +output "gitops_repo_application_token" { + description = "The token for the application repo" + value = module.gitops_repo.application_token + sensitive = true +} +output "gitops_repo_application_paths" { + description = "The paths in the application repo" + value = module.gitops_repo.application_paths +} +output "gitops_repo_gitops_config" { + description = "Config information regarding the gitops repo structure" + value = module.gitops_repo.gitops_config +} +output "gitops_repo_git_credentials" { + description = "The credentials for the gitops repo(s)" + value = module.gitops_repo.git_credentials + sensitive = true +} +output "gitops_repo_server_name" { + description = "The name of the cluster that will be configured for gitops" + value = module.gitops_repo.server_name +} +output "gitops_repo_sealed_secrets_cert" { + description = "The certificate used to encrypt sealed secrets" + value = module.gitops_repo.sealed_secrets_cert +} +output "gitops-sonarqube_name" { + description = "The name of the module" + value = module.gitops-sonarqube.name +} +output "gitops-sonarqube_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-sonarqube.branch +} +output "gitops-sonarqube_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-sonarqube.namespace +} +output "gitops-sonarqube_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-sonarqube.server_name +} +output "gitops-sonarqube_layer" { + description = "The layer where the module is deployed" + value = module.gitops-sonarqube.layer +} +output "gitops-sonarqube_type" { + description = "The type of module where the module is deployed" + value = module.gitops-sonarqube.type +} +output "gitops-sonarqube_postgresql" { + description = "Properties for an existing postgresql database" + value = module.gitops-sonarqube.postgresql +} +output "gitops-swagger-editor_name" { + description = "The name of the module" + value = module.gitops-swagger-editor.name +} +output "gitops-swagger-editor_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-swagger-editor.branch +} +output "gitops-swagger-editor_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-swagger-editor.namespace +} +output "gitops-swagger-editor_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-swagger-editor.server_name +} +output "gitops-swagger-editor_layer" { + description = "The layer where the module is deployed" + value = module.gitops-swagger-editor.layer +} +output "gitops-swagger-editor_type" { + description = "The type of module where the module is deployed" + value = module.gitops-swagger-editor.type +} +output "gitops-tekton-resources_name" { + description = "The name of the module" + value = module.gitops-tekton-resources.name +} +output "gitops-tekton-resources_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-tekton-resources.branch +} +output "gitops-tekton-resources_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-tekton-resources.namespace +} +output "gitops-tekton-resources_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-tekton-resources.server_name +} +output "gitops-tekton-resources_layer" { + description = "The layer where the module is deployed" + value = module.gitops-tekton-resources.layer +} +output "gitops-tekton-resources_type" { + description = "The type of module where the module is deployed" + value = module.gitops-tekton-resources.type +} +output "util-clis_bin_dir" { + description = "Directory where the clis were downloaded" + value = module.util-clis.bin_dir +} +output "gitops-buildah-unprivileged_name" { + description = "The name of the module" + value = module.gitops-buildah-unprivileged.name +} +output "gitops-buildah-unprivileged_branch" { + description = "The branch where the module config has been placed" + value = module.gitops-buildah-unprivileged.branch +} +output "gitops-buildah-unprivileged_namespace" { + description = "The namespace where the module will be deployed" + value = module.gitops-buildah-unprivileged.namespace +} +output "gitops-buildah-unprivileged_server_name" { + description = "The server where the module will be deployed" + value = module.gitops-buildah-unprivileged.server_name +} +output "gitops-buildah-unprivileged_layer" { + description = "The layer where the module is deployed" + value = module.gitops-buildah-unprivileged.layer +} +output "gitops-buildah-unprivileged_type" { + description = "The type of module where the module is deployed" + value = module.gitops-buildah-unprivileged.type +} diff --git a/2-standard/1-aro/220-dev-tools/providers.tf b/2-standard/1-aro/220-dev-tools/providers.tf index 459ee95..9aa08ee 100644 --- a/2-standard/1-aro/220-dev-tools/providers.tf +++ b/2-standard/1-aro/220-dev-tools/providers.tf @@ -2,5 +2,28 @@ provider "gitops" { + + bin_dir = module.util-clis.bin_dir + default_host = var.gitops_default_host + default_org = var.gitops_default_org + default_username = var.gitops_default_username + default_token = var.gitops_default_token + default_ca_cert = var.gitops_default_ca_cert + host = var.gitops_host + org = var.gitops_org + project = var.gitops_project + repo = var.gitops_repo + username = var.gitops_username + token = var.gitops_token + branch = var.gitops_branch + server_name = var.gitops_server_name + ca_cert = var.gitops_ca_cert + ca_cert_file = var.gitops_ca_cert_file +} +provider "clis" { + + + + } \ 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 index 94ccef4..b9e21c7 100644 --- a/2-standard/1-aro/220-dev-tools/terragrunt.hcl +++ b/2-standard/1-aro/220-dev-tools/terragrunt.hcl @@ -34,10 +34,10 @@ dependency "gitops" { } 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 + gitops_repo_host = dependency.gitops.outputs.gitops_repo_config_host + gitops_repo_org = dependency.gitops.outputs.gitops_repo_config_org + gitops_repo_repo = dependency.gitops.outputs.gitops_repo_config_name + gitops_repo_project = dependency.gitops.outputs.gitops_repo_config_project + gitops_repo_username = dependency.gitops.outputs.gitops_repo_config_username + gitops_repo_token = dependency.gitops.outputs.gitops_repo_config_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 index 5a863ab..4bdf83a 100644 --- a/2-standard/1-aro/220-dev-tools/variables.tf +++ b/2-standard/1-aro/220-dev-tools/variables.tf @@ -23,6 +23,81 @@ variable "gitops-artifactory_persistence" { description = "Flag to indicate if persistence should be enabled" default = true } +variable "gitops_default_host" { + type = string + description = "the value of gitops_default_host" + default = "" +} +variable "gitops_default_org" { + type = string + description = "the value of gitops_default_org" + default = "" +} +variable "gitops_default_username" { + type = string + description = "the value of gitops_default_username" + default = "" +} +variable "gitops_default_token" { + type = string + description = "the value of gitops_default_token" + default = "" +} +variable "gitops_default_ca_cert" { + type = string + description = "the value of gitops_default_ca_cert" + default = "" +} +variable "gitops_host" { + type = string + description = "The host name of the gitops repository (GitHub, Github Enterprise, Gitlab, Bitbucket, Azure DevOps, and Gitea servers are supported)." + default = "" +} +variable "gitops_org" { + type = string + description = "The organization on the git server where the repsitory will be located. If not provided the org will default to the username." + default = "" +} +variable "gitops_project" { + type = string + description = "The Azure DevOps project in the git server. This value is only applied for Azure DevOps servers." + default = "" +} +variable "gitops_repo" { + type = string + description = "The name of the repository in the org on the git server." + default = "" +} +variable "gitops_username" { + type = string + description = "The username used to access the git server." + default = "" +} +variable "gitops_token" { + type = string + description = "The token used to access the git server." + default = "" +} +variable "gitops_branch" { + type = string + description = "The name of the branch in the gitops repository where the config will be stored." + default = "main" +} +variable "gitops_server_name" { + type = string + description = "The name of the server the configuration with which the configuration will be associated." + default = "default" +} +variable "gitops_ca_cert" { + type = string + description = "The ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" +} +variable "gitops_ca_cert_file" { + type = string + description = "The file containing the ca certificate used to sign the self-signed certificate used by the git server, if applicable." + default = "" +} variable "gitops-dashboard_cluster_type" { type = string description = "The cluster type (openshift or ocp3 or ocp4 or kubernetes)" diff --git a/2-standard/1-aro/220-dev-tools/version.tf b/2-standard/1-aro/220-dev-tools/version.tf index 5034007..da8ce2a 100644 --- a/2-standard/1-aro/220-dev-tools/version.tf +++ b/2-standard/1-aro/220-dev-tools/version.tf @@ -2,6 +2,12 @@ terraform { required_providers { gitops = { source = "cloud-native-toolkit/gitops" + version = "0.11.1" + } + + clis = { + source = "cloud-native-toolkit/clis" + version = "0.2.4" } } diff --git a/2-standard/1-aro/README.md b/2-standard/1-aro/README.md index a1c95e0..878834c 100644 --- a/2-standard/1-aro/README.md +++ b/2-standard/1-aro/README.md @@ -106,7 +106,11 @@ The automation is delivered in a number of layers that are applied in order. Lay 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. +3. 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.\ + +4. If using your Azure account, use the interactive approach in `launch.sh` to login to the Azure CLI. + +4. (Optional) If using a service principal instead of your Azure account, [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 @@ -120,15 +124,13 @@ The automation is delivered in a number of layers that are applied in order. Lay "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. + 2. Give permissions to the service principal to create other service principals and the ARO cluster (refer [here](./sp-setup.md) for details) -6. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. +5. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. ```shell - brew install docker colima - colima start + $ brew install docker colima + $ colima start ``` ### Setup @@ -136,7 +138,7 @@ The automation is delivered in a number of layers that are applied in order. Lay 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 + $ 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 @@ -162,7 +164,7 @@ The automation is delivered in a number of layers that are applied in order. Lay - **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 + $ 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. @@ -178,8 +180,8 @@ The automation is delivered in a number of layers that are applied in order. Lay From the **/workspace/current** directory, run the following: -``` -./apply-all.sh -a +```shell +$ ./apply-all.sh -a ``` The script will run through each of the terraform layers in sequence to provision the entire infrastructure. @@ -189,27 +191,26 @@ The script will run through each of the terraform layers in sequence to provisio From the **/workspace/current** directory, change directory into each of the layer subdirectories and run the following: ```shell -terragrunt init -terragrunt apply -auto-approve +$ 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 +```shell +$ /workspaces/current/show-login.sh ``` ### Connect to the cluster -Once the installation is complete, cluster access can be obtained using the downloaded VPN configuration file in the `101-azure-vnet-std` subdirectory or by using the check-vpn script as follows: -``` +Once the installation is complete, cluster access can be obtained using the downloaded VPN configuration file (`*.ovpn`) in the `101-azure-vnet-std` subdirectory or by using the check-vpn script as follows: +```shell $ cd /workspace/current/105-azure-aro-std/ $ ../check-vpn.sh ``` The cluster access can then be obtained using the kubeconfig file as follows: -``` +```shell $ cd /workspace/current/105-azure-aro-std/ $ export KUBECONFIG="./.kube/config" $ oc get nodes diff --git a/README.md b/README.md index 8a668db..d0e6cc3 100644 --- a/README.md +++ b/README.md @@ -30,15 +30,9 @@ This set of automation packages was generated using the open-source [`isacable`] 1. Have access to an Azure subscription with "Owner" and "User Access Administrator" roles. The user must be able to create a service prinicpal. -2. Configure an Azure DNS zone with a valid public domain (refer to the README [here](1-quickstart/2-ipi/README.md) for more information) +2. Obtain a Red Hat [OpenShift installer pull secret](https://console.redhat.com/openshift/install/pull-secret) -3. Create a service principal to be used to create the cluster (refer to the README [here](1-quickstart/2-ipi/README.md) for more information) - - If using ARO, note that there are additional permissions needed for the service principal (refer to the README [here](1-quickstart/1-aro/sp-setup.md) for more information) - -4. Obtain a Red Hat [OpenShift installer pull secret](https://console.redhat.com/openshift/install/pull-secret) - -5. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. +3. (Optional) Install and start Colima to run the terraform tools in a local bootstrapped container image. On Mac with brew (note that this only works with Intel based Macs at this time): ```shell @@ -46,6 +40,14 @@ This set of automation packages was generated using the open-source [`isacable`] colima start ``` +#### IPI Prerequisites + +1. Configure an Azure DNS zone with a valid public domain (refer to the README [here](1-quickstart/2-ipi/README.md) for more information) + +2. Create a service principal to be used to create the cluster (refer to the README [here](1-quickstart/2-ipi/README.md) for more information) + + If using ARO, note that there are additional permissions needed for the service principal (refer to the README [here](1-quickstart/1-aro/sp-setup.md) for more information) + ### Planning 1. Determine which flavor of reference architecture you will provision: Quick Start or Standard. @@ -61,16 +63,16 @@ This set of automation packages was generated using the open-source [`isacable`] ```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 - - **TF_VAR_client_id** - The id of the service principal with Owner and User Administrator access to the subscription for cluster creation - - **TF_VAR_client_secret** - The password of the service principal with Owner and User Administrator access to the subscription for cluster creation +3. Provide values for the variables in **credentials.properties** (**Note:** `*.properties` has been added to **.gitignore** to ensure that the file containing the credentials cannot be checked into Git.) + - **TF_VAR_subscription_id** - (Optional) The Azure subscription id where the cluster will be deployed + - **TF_VAR_tenant_id** - (Optional) The Azure tenant id that owns the subscription + - **TF_VAR_client_id** - (Optional) The id of the service principal with Owner and User Administrator access to the subscription for cluster creation + - **TF_VAR_client_secret** - (Optional) The password of the service principal with Owner and User Administrator access to the subscription for cluster creation - **TF_VAR_pull_secret** - The contents of the Red Hat OpenShift pull secret - **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. -4. Run **./launch.sh**. This will start a container image with the prompt opened in the `/terraform` directory, pointed to the repo directory. +4. Run **./launch.sh**. This will start a container image and can walk through the setup. If you do not select to setup the workspace, continue to the next step, otherwise, you can build straight from the launch script. 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] diff --git a/az-login.sh b/az-login.sh new file mode 100755 index 0000000..244dc2e --- /dev/null +++ b/az-login.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +STOP_FILE="$(pwd)/.stop" + +function manageExit() { + echo + echo "Stopping login" + touch $STOP_FILE + exit 1; +} + +trap manageExit INT +trap manageExit TERM + +az account show > /dev/null 2>&1 +if (( $? != 0 )); then + if [[ -n $TF_VAR_client_id ]] && [[ -n $TF_VAR_client_secret ]] && [[ -n $TF_VAR_tenant_id ]] && [[ -n $TF_VAR_subscription_id ]]; then + # Login with service principal details + az login --service-principal -u "$TF_VAR_client_id" -p "$TF_VAR_client_secret" -t "$TF_VAR_tenant_id" > /dev/null 2>&1 + if (( $? != 0 )); then + echo "ERROR: Unable to login to service principal. Check supplied details in credentials.properties." + touch $STOP_FILE + exit 1 + else + echo "Successfully logged on with service principal" + fi + az account set --subscription "$TF_VAR_subscription_id" > /dev/null 2>&1 + if (( $? != 0 )); then + echo "ERROR: Unable to use subscription id $TF_VAR_subscription_id. Please check and try agian." + touch $STOP_FILE + exit 1 + else + echo "Successfully changed to subscription : $(az account show -o yaml | yq '.name')" + fi + else + echo "Please login to Azure CLI to continue" + az login + fi +else + echo "Using existing Azure CLI login" +fi + diff --git a/azure-metadata.yaml b/azure-metadata.yaml index 357132d..8f23c20 100644 --- a/azure-metadata.yaml +++ b/azure-metadata.yaml @@ -14,6 +14,24 @@ distributions: code: ipi - name: Azure Red Hat OpenShift code: aro +cert_options: + - name: ACME LetsEncrypt + code: acme + - name: Bring your own TLS Certificates + code: byo +git_hosts: + - name: Github + code: github.com + - name: Github Enterprise + code: + - name: Gitlab + code: + - name: Bitbucket + code: + - name: Azure DevOps + code: + - name: Gitea + code: gitea regions: - name: South Africa North code: southafricanorth diff --git a/credentials.template b/credentials.template index 6b9d973..79e7655 100644 --- a/credentials.template +++ b/credentials.template @@ -1,6 +1,10 @@ ## Copy this file to credentials.properties and populate values ## Don't include quotes around the value + +### +# If using your own login details and not a service principal, comment out the Azure credentials. +# ## The Azure subscription where the cluster is to be deployed. TF_VAR_subscription_id= @@ -13,25 +17,32 @@ TF_VAR_client_secret= ## The Azure tenant id which owns the subscription TF_VAR_tenant_id= +### +# Red Hat pull secret is required for gitops and other tools ## The Red Hat OpenShift pull secret TF_VAR_pull_secret= -## Email for auto-generated certificate -TF_VAR_acme_registration_email= - +### General ## Flag used to for automation testing. Typically leave this as none # There is a limit on the number of certificates that can be issued each week. If you are doing testing, change this to 'staging' to leverage staging certificates. # Staging certificates will not allow access to web console, but are not subject to the same issue cap as valid certificates from LetsEncrypt. TF_VAR_testing=none +### Portworx ## Portworx specification file # This needs to be a base64 encoded string of the Portworx specification yaml (refer to https://github.com/cloud-native-toolkit/terraform-azure-portworx) # This can be left empty if the portworx spec file path is specified in the terraform.tfvars file. TF_VAR_portworx_spec= +### Git Host credentials. Leave blank for GiTea ## The username on github.com that will be used to provision the gitops repository. Do not include values if using GiTea. TF_VAR_gitops_repo_username= ## The personal access token that will be used to authenticate to github.com to provision the gitops repository. (The user should have necessary access in the org to create the repository and the token should have `delete_repo` permission.) TF_VAR_gitops_repo_token= ## (Optional) The github.com org where the gitops repository will be provisioned. If not provided the org will default to the username. TF_VAR_gitops_repo_org= + +### +# Following only applicable to OpenShift IPI distributions +## Email for auto-generated certificate +TF_VAR_acme_registration_email= diff --git a/launch.sh b/launch.sh index c5aa355..1d50808 100755 --- a/launch.sh +++ b/launch.sh @@ -4,14 +4,20 @@ SCRIPT_DIR="$(cd $(dirname $0); pwd -P)" SRC_DIR="${SCRIPT_DIR}" +STOP_FILE="${SCRIPT_DIR}/.stop" -DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.4.20" +DOCKER_IMAGE="quay.io/cloudnativetoolkit/cli-tools-azure:v1.2-v0.6.0" 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}" +# Clean up stop file if it exists (this is used for flow control with container) +if [[ -e $STOP_FILE ]]; then + rm -f $STOP_FILE +fi + DOCKER_CMD="docker" ${DOCKER_CMD} kill ${CONTAINER_NAME} 1> /dev/null 2> /dev/null ${DOCKER_CMD} rm ${CONTAINER_NAME} 1> /dev/null 2> /dev/null @@ -26,14 +32,50 @@ if [[ -f "credentials.properties" ]]; then ENV_FILE="--env-file credentials.properties" 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:/workspaces \ - ${ENV_FILE} \ - -w /terraform \ - ${DOCKER_IMAGE} +echo -n "Setup workspace (y/n) [Y]: " +read SETUP +echo + + echo "Initializing container ${CONTAINER_NAME} from ${DOCKER_IMAGE} and setting up environment" + ${DOCKER_CMD} run -itd --name ${CONTAINER_NAME} \ + --device /dev/net/tun --cap-add=NET_ADMIN \ + -v ${SRC_DIR}:/terraform \ + -v workspace:/workspaces \ + -w /terraform \ + ${ENV_FILE} \ + ${DOCKER_IMAGE} + +if [[ "${SETUP^}" == "Y" ]] || [[ -z $SETUP ]]; then + + # Check if service principal details provided, if not login to Azure CLI + echo "Checking credentials & logging into Azure CLI" + ${DOCKER_CMD} exec -it -w /terraform ${CONTAINER_NAME} sh -c "/terraform/az-login.sh" + + if [[ -e $STOP_FILE ]]; then + rm -f $STOP_FILE + exit 1; + fi + + ${DOCKER_CMD} exec -it -w /terraform ${CONTAINER_NAME} sh -c "cd /terraform ; /terraform/setup-workspace.sh -i" + + if [[ -e $STOP_FILE ]]; then + rm -f $STOP_FILE + exit 1; + fi + + echo -n "Build environment (only yes will be accepted) : " + read BUILD + + if [[ "${BUILD^^}" == "YES" ]]; then + ${DOCKER_CMD} exec -it -w /workspaces/current ${CONTAINER_NAME} sh -c "./apply-all.sh -a" + else + echo + echo "Attaching to running container..." + echo + echo "Run \"cd /workspaces/current && ./apply-all.sh -a\" to start build." + fi +else + echo "Attaching to running container..." +fi -echo "Attaching to running container..." ${DOCKER_CMD} attach ${CONTAINER_NAME} diff --git a/setup-workspace.sh b/setup-workspace.sh index ed18ad6..55f2dae 100755 --- a/setup-workspace.sh +++ b/setup-workspace.sh @@ -3,14 +3,9 @@ SCRIPT_DIR=$(cd $(dirname $0); pwd -P) METADATA_FILE="${SCRIPT_DIR}/azure-metadata.yaml" -## For now default to quickstart -#FLAVOR="quickstart" -#STORAGE="default" -#PREFIX_NAME="" -REGION="eastus" -#DIST="ipi" - -Usage() +INTERACT=0 + +function usage() { echo "Creates a workspace folder and populates it with architectures." echo @@ -24,16 +19,19 @@ Usage() echo " -r (optional) the region where the infrastructure will be provisioned" echo " -b (optional) the banner text that should be shown at the top of the cluster" echo " -g (optional) the git host that will be used for the gitops repo. If left blank gitea will be used by default. (Github, Github Enterprise, Gitlab, Bitbucket, Azure DevOps, and Gitea servers are supported)" + echo " -i activates interactive mode to input required values" echo " -h Print this help" echo } # Get the options -while getopts ":f:d:s:c:n:r:b:g:" option; do +while getopts ":f:d:s:c:n:r:b:g:hi" option; do case $option in h) # display Help - Usage + usage exit 1;; + i) # Interactive mode + INTERACT=1;; f) # Enter a name FLAVOR=$OPTARG;; d) # Enter a name @@ -52,11 +50,220 @@ while getopts ":f:d:s:c:n:r:b:g:" option; do BANNER=$OPTARG;; \?) # Invalid option echo "Error: Invalid option" - Usage + usage exit 1;; esac done +function menu() { + local item i=1 numItems=$# + + for item in "$@"; do + printf '%s %s\n' "$((i++))" "$item" + done >&2 + + while :; do + printf %s "${PS3-#? }" >&2 + read -r input + if [[ -z $input ]]; then + break + elif [[ $input < 1 ]] || [[ $input > $numItems ]]; then + echo "Invalid Selection. Enter numnber next to item." >&2 + continue + fi + break + done + + if [[ -n $input ]]; then + printf %s "${@: input:1}" + fi +} + +function interact() { + local DEFAULT_FLAVOR="quickstart" + local DEFAULT_DIST="aro" + local DEFAULT_CERT="acme" + local DEFAULT_STORAGE="default" + local DEFAULT_REGION="australiaeast" + local DEFAULT_BANNER="$DEFAULT_FLAVOR" + local DEFAULT_GITHOST="gitea" + local MAX_PREFIX_LENGTH=5 + local MAX_BANNER_LENGTH=25 + + IFS=$'\n' + + if [[ -z "$(which yq)" ]]; then + echo "ERROR: yq not found. yq is required for interactive mode." + echo "If yq is intalled, please ensure it is included in the PATH environment variable." + exit 1; + fi + + # Get flavor + echo + read -r -d '' -a FLAVORS < <(yq '.flavors[].name' $METADATA_FILE | sort -u) + PS3="Select the architecture flavor [$(yq ".flavors[] | select(.code == \"$DEFAULT_FLAVOR\") | .name" $METADATA_FILE)]: " + flavor=$(menu "${FLAVORS[@]}") + case $flavor in + '') FLAVOR="$DEFAULT_FLAVOR"; ;; + *) FLAVOR="$(yq ".flavors[] | select(.name == \"$flavor\") | .code" $METADATA_FILE)"; ;; + esac + + # Get disti + echo + read -r -d '' -a DISTS < <(yq '.distributions[].name' $METADATA_FILE | sort -u) + PS3="Select the distribution [$(yq ".distributions[] | select(.code == \"$DEFAULT_DIST\") | .name" $METADATA_FILE)]: " + dist=$(menu "${DISTS[@]}") + case $dist in + '') DIST="$DEFAULT_DIST"; ;; + *) DIST="$(yq ".distributions[] | select(.name == \"$dist\") | .code" $METADATA_FILE)"; ;; + esac + + # 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 + + # Get region + echo + read -r -d '' -a AREAS < <(yq '.regions[].area' $METADATA_FILE | sort -u) + DEFAULT_AREA="$(yq ".regions[] | select(.code == \"$DEFAULT_REGION\") | .area" $METADATA_FILE)" + PS3="Select the deployment area [$DEFAULT_AREA]: " + area=$(menu "${AREAS[@]}") + case $area in + '') AREA="$DEFAULT_AREA"; ;; + *) AREA=$area; ;; + esac + + echo + read -r -d '' -a REGIONS < <(yq ".regions[] | select(.area == \"${AREA}\") | .name" $METADATA_FILE | sort -u) + if [[ $AREA != $DEFAULT_AREA ]]; then + DEFAULT_REGION="$(yq ".regions[] | select(.name == \"${REGIONS[0]}\") | .code" $METADATA_FILE)" + fi + PS3="Select the region within ${AREA} [$(yq ".regions[] | select(.code == \"$DEFAULT_REGION\") | .name" $METADATA_FILE)]: " + region=$(menu "${REGIONS[@]}") + case $region in + '') REGION="$DEFAULT_REGION"; ;; + *) REGION="$(yq ".regions[] | select(.name == \"$region\") | .code" $METADATA_FILE)"; ;; + esac + + # Get storage + echo + read -r -d '' -a STORAGE_OPTIONS < <(yq '.storage[].name' $METADATA_FILE | sort -u) + PS3="Select the storage [$(yq ".storage[] | select(.code == \"$DEFAULT_STORAGE\") | .name" $METADATA_FILE)]: " + storage=$(menu "${STORAGE_OPTIONS[@]}") + case $storage in + '') STORAGE="$DEFAULT_STORAGE"; ;; + *) STORAGE="$(yq ".storage[] | select(.name == \"$storage\") | .code" $METADATA_FILE)"; ;; + esac + + # Get cert + if [[ "${DIST}" == "ipi" ]]; then + echo + read -r -d '' -a CERT_OPTIONS < <(yq ".cert_options[].name" $METADATA_FILE | sort -u) + PS3="Select the certificate type [$(yq ".cert_options[] | select(.code == \"$DEFAULT_CERT\") | .name" $METADATA_FILE)] : " + cert=$(menu "${CERT_OPTIONS[@]}") + case $cert in + '') CERT="$DEFAULT_CERT"; ;; + *) CERT="$(yq ".cert_options[] | select(.name == \"$cert\") | .code" $METADATA_FILE)"; ;; + esac + else + CERT="" + fi + + # Get name prefix + local name="" + chars=abcdefghijklmnopqrstuvwxyz0123456789 + for i in {1..5}; do + name+=${chars:RANDOM%${#chars}:1} + done + + + while [[ -z $INPUT_NAME ]]; do + echo + echo -n -e "Enter name prefix [$name]: " + read input + + if [[ -n $input ]]; then + if [[ $input =~ [a-zA-Z0-9] ]] && (( ${#input} <= $MAX_PREFIX_LENGTH )) ; then + INPUT_NAME=$input + else + echo "Invalid prefix name. Must be less than $MAX_PREFIX_LENGTH, not contain spaces and be alphanumeric characters only" + fi + elif [[ -z $input ]]; then + INPUT_NAME=$name + fi + done + + if [[ -n $INPUT_NAME ]]; then + PREFIX_NAME="${INPUT_NAME}" + else + PREFIX_NAME="${NAME}" + fi + + # Get git host + echo + read -r -d '' -a GIT_HOST_OPTIONS < <(yq ".git_hosts[].name" $METADATA_FILE) + PS3="Select GitOps Host Type [$(yq ".git_hosts[] | select(.code == \"$DEFAULT_GITHOST\") | .name" $METADATA_FILE)]: " + githost=$(menu "${GIT_HOST_OPTIONS[@]}") + case $githost in + '') GIT_HOST_CODE="$DEFAULT_GITHOST"; ;; + *) GIT_HOST_CODE="$(yq ".git_hosts[] | select(.name == \"$githost\") | .code" $METADATA_FILE)"; ;; + esac + + if [[ -z $GIT_HOST_CODE ]]; then + echo + echo -n "Please enter hostname for $githost : " + read GIT_HOST + elif [[ $GIT_HOST_CODE == "gitea" ]]; then + GIT_HOST="" + else + GIT_HOST=$GIT_HOST_CODE + fi + + # Get banner + echo + echo -n "Enter title for console banner [$DEFAULT_BANNER]: " + read BANNER_NAME + + if [[ -n $BANNER_NAME ]]; then + BANNER="${BANNER_NAME}" + else + BANNER="${DEFAULT_BANNER}" + fi + + echo + echo "Setting up workspace with the following" + echo "Architecture (Flavor) = $FLAVOR" + echo "Region/Location = $REGION" + echo "Distribution = $DIST" + echo "Storage = $STORAGE" + echo "Name Prefix = $PREFIX_NAME" + if [[ $DIST == "ipi" ]]; then + echo "Ingress Certificate = $CERT" + fi + echo "GitOps Host = $GIT_HOST" + echo "Console Banner Title = $BANNER" + + echo -n "Confirm setup workspace with these settings (Y/N) [Y]: " + read confirm + + if [[ -z $confirm ]]; then + confirm="Y" + fi + + if [[ ${confirm^} != "Y" ]]; then + echo "Exiting without setting up environment" >&2 + touch /terraform/.stop + exit 1 + fi + +} + +if (( $INTERACT != 0 )); then + interact +fi + if [[ -z "${FLAVOR}" ]]; then FLAVORS=($(find "${SCRIPT_DIR}" -type d -maxdepth 1 | grep "${SCRIPT_DIR}/" | sed -E "s~${SCRIPT_DIR}/~~g" | grep -E "^[0-9]-" | sort | sed -e "s/[0-9]-//g" | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1')) @@ -211,7 +418,13 @@ else for i in {1..5}; do NAME+=${chars:RANDOM%${#chars}:1} done - PREFIX_NAME="${NAME}" + echo "Enter name prefix (default = ${NAME}):" + read INPUT_NAME + if [[ -n $INPUT_NAME ]]; then + PREFIX_NAME="${INPUT_NAME}" + else + PREFIX_NAME="${NAME}" + fi fi if [[ -z "${GIT_HOST}" ]]; then diff --git a/show-login.sh b/show-login.sh index d4d09eb..7759e62 100755 --- a/show-login.sh +++ b/show-login.sh @@ -2,27 +2,69 @@ # Add check that cluster has been built -cd 105-azure-ocp-ipi -SERVER_URL=$(terragrunt output -raw server_url ) -USERNAME=$(terragrunt output -raw username ) -PASSWORD=$(terragrunt output -raw password ) -BIN_DIR=$(terragrunt output -raw bin_dir ) -CONSOLE_URL=$(terragrunt output -raw consoleURL ) +WORK_DIR="/workspaces/current" +ACME_DIR="110-azure-acme-certificate" -# Add check if Certificate has been completed +cd $WORK_DIR + +OCP_DIR=$(cat layers.yaml | grep names_105 | awk '{printf $2}' | sed 's/\"//g') +PRIVATE=0 +if [[ -d $OCP_DIR ]]; then + if [[ -n $(echo $OCP_DIR | grep aro) ]]; then # ARO + BIN_DIR="${WORK_DIR}/bin" + SERVER_URL=$(cat ${WORK_DIR}/${OCP_DIR}/.tmp/aro/output.json | ${BIN_DIR}/jq -r '.result.properties.apiserverProfile.url') + CONSOLE_URL=$(cat ${WORK_DIR}/${OCP_DIR}/.tmp/aro/output.json | ${BIN_DIR}/jq -r '.consoleUrl') + USERNAME=$(cat ${WORK_DIR}/${OCP_DIR}/.tmp/aro/credentials.json | ${BIN_DIR}/jq -r '.kubeadminUsername') + PASSWORD=$(cat ${WORK_DIR}/${OCP_DIR}/.tmp/aro/credentials.json | ${BIN_DIR}/jq -r '.kubeadminPassword') + if [[ $(cat ${WORK_DIR}/${OCP_DIR}/.tmp/aro/output.json | ${BIN_DIR}/jq -r '.result.properties.apiserverProfile.visibility') -eq "Private" ]]; then + PRIVATE=1 + fi + else # IPI + cd $OCP_DIR + SERVER_URL=$(terragrunt output -raw server_url ) + USERNAME=$(terragrunt output -raw username ) + PASSWORD=$(terragrunt output -raw password ) + BIN_DIR=$(terragrunt output -raw bin_dir ) + CONSOLE_URL=$(terragrunt output -raw consoleURL ) + fi +else + echo "ERROR: Openshift directory $OCP_DIR not found." + exit 1; +fi + +OVPN_FILE=$(find "${WORK_DIR}" -name "*.ovpn" | head -1) -cd ../110-azure-acme-certificate echo "To login via command line:" -if [ "$(terragrunt output -raw ca_cert)" == "" ]; then - echo "$BIN_DIR/oc login -s=$SERVER_URL -u=$USERNAME -p=$PASSWORD" +cd $WORK_DIR +if [[ -d $ACME_DIR ]]; then + cd $ACME_DIR + if [ "$(terragrunt output -raw ca_cert)" == "" ]; then + echo "$BIN_DIR/oc login -s=$SERVER_URL -u=$USERNAME -p=$PASSWORD" + else + CA_CRT="./110-azure-acme-certificate/certs/apps-issuer-ca.crt" + echo "$BIN_DIR/oc login -s=$SERVER_URL -u=$USERNAME -p=$PASSWORD --certificate-authority=$CA_CRT" + fi else - CA_CRT="./110-azure-acme-certificate/certs/apps-issuer-ca.crt" - echo "$BIN_DIR/oc login -s=$SERVER_URL -u=$USERNAME -p=$PASSWORD --certificate-authority=$CA_CRT" + if [[ $PRIVATE ]]; then + echo + echo "Connect to VPN using the client configuration $OVPN_FILE" + echo "If in container, a quick way is as follows:" + echo "cd ${WORK_DIR}/200-openshift-gitops && ${WORK_DIR}/check-vpn.sh && cd -" + echo + fi + echo "$BIN_DIR/oc login -s=$SERVER_URL -u=$USERNAME -p=$PASSWORD" fi # Show console URL echo "" echo "To login to the console (may take a few minutes for certificate to be applied to cluster):" +if [[ $PRIVATE ]]; then + echo + echo "Connect to VPN using the client configuration $OVPN_FILE" + echo "If in container, a quick way is as follows:" + echo "cd ${WORK_DIR}/200-openshift-gitops && ${WORK_DIR}/check-vpn.sh && cd -" + echo +fi echo "Console URL - ${CONSOLE_URL}" echo "Username - ${USERNAME}" echo "Password - ${PASSWORD}" diff --git a/terraform.tfvars.template-quickstart-aro b/terraform.tfvars.template-quickstart-aro index 83bfd8a..210ed7f 100644 --- a/terraform.tfvars.template-quickstart-aro +++ b/terraform.tfvars.template-quickstart-aro @@ -11,10 +11,10 @@ resource_group_name="PREFIXrg" region="REGION" ## The number of worker nodes to create -cluster__count=3 +cluster_worker_count=3 ## The type of worker nodes to create -cluster_flavor="Standard_D4s_v3" +cluster_worker_flavor="Standard_D4s_v3" ###################### #### Portworx storage diff --git a/terraform.tfvars.template-standard-aro b/terraform.tfvars.template-standard-aro index dbe1dcd..43e1a3d 100644 --- a/terraform.tfvars.template-standard-aro +++ b/terraform.tfvars.template-standard-aro @@ -11,10 +11,10 @@ resource_group_name="PREFIX-rg" region="REGION" ## The number of worker nodes to create -cluster__count=3 +cluster_worker_count=3 ## The type of worker nodes to create -cluster_flavor="Standard_D4s_v3" +cluster_worker_flavor="Standard_D4s_v3" ###################### #### Portworx storage