Skip to content

Commit ee98427

Browse files
authored
Add terraform scripts to provision ODM landing zone on IBM Cloud (#191)
* added terraform for ODM on ROKS * updated readme
1 parent 7c23ffe commit ee98427

File tree

12 files changed

+742
-4
lines changed

12 files changed

+742
-4
lines changed

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
11
*.iml
22
output
33
/.vscode
4+
5+
6+
# Local .terraform directories
7+
**/.terraform/*
8+
# .tfstate files
9+
*.tfstate
10+
*.tfstate.*
11+
*.terraform.lock.hcl
12+
# Exclude all .tfvars files, which are likely to contain sentitive data, such as
13+
# password, private keys, and other secrets. These should not be part of version
14+
# control as they are data points which are potentially sensitive and subject
15+
# to change depending on the environment.
16+
#
17+
# *.tfvars

platform/roks/README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,22 @@ Then, create an [IBM Cloud Account](https://cloud.ibm.com/registration).
4343

4444
### 1. Prepare your environment (20 min)
4545

46-
Create your IBM Cloud account and set up your first ROKS cluster following this [IBM Cloud tutorial](https://cloud.ibm.com/docs/openshift?topic=openshift-openshift_tutorial&locale=en). Then, create a project for ODM deployment:
46+
1. Create your IBM Cloud account
4747

48-
```bash
49-
oc new-project odm-tutorial
50-
```
48+
1. Follow the steps to provision the full infrastructure via Terraform in this [README](./terraform/README.md)
49+
50+
> Should you want to provision the cluster via the Console, you could follow this [IBM Cloud tutorial](https://cloud.ibm.com/docs/openshift?topic=openshift-openshift_tutorial&locale=en).
51+
52+
1. Then, create an OpenShift project for ODM deployment:
53+
54+
```bash
55+
oc new-project odm-tutorial
56+
```
5157

5258
### 2. Prepare your environment for the ODM installation (5 min)
5359

5460
To get access to the ODM material, you must have an IBM entitlement key to pull the images from the IBM Cloud Container registry.
61+
5562
This is what will be used in the next step of this tutorial.
5663

5764
#### a. Retrieve your entitled registry key

platform/roks/terraform/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Provision an ODM landing zone on IBM CLoud
2+
3+
> Estimated duration: 60 mins
4+
5+
These Terraform scripts will provision the following Cloud Services in IBM Cloud:
6+
7+
* a Resource Group to host resources
8+
* a VPC with 3 subnets across a MZR (Multi Zone Region)
9+
* a managed OpenShift cluster (ROKS)
10+
* a managed Postgres Database
11+
12+
You can then ssh into the newly created VSI.
13+
14+
| Terraform | Estimation Duration |
15+
| --------- | --------- |
16+
| Apply | ~60 mins |
17+
| Destroy | ~5-10 mins |
18+
19+
## Before you begin
20+
21+
This lab requires the following command lines:
22+
23+
* [IBM Cloud CLI](https://github.com/IBM-Cloud/ibm-cloud-cli-release/releases)
24+
* [Terraform CLI](https://developer.hashicorp.com/terraform/downloads)
25+
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
26+
* [jq CLI JSON processor](https://jqlang.github.io/jq/download/)
27+
28+
> Unless you are Administrator of the Cloud Account, you need permissions to be able to provision VPC Resources. Ask the Administrator run the Terraform in `iam` folder.
29+
30+
## Provisioning Steps
31+
32+
1. Clone this repository
33+
34+
```sh
35+
git clone https://github.com/lionelmace/learn-ibm-terraform
36+
```
37+
38+
1. Login to IBM Cloud
39+
40+
```sh
41+
ibmcloud login
42+
```
43+
44+
1. Create and store the value of an API KEY as environment variable
45+
46+
```sh
47+
export IBMCLOUD_API_KEY=$(ibmcloud iam api-key-create my-api-key --output json | jq -r .apikey)
48+
```
49+
50+
> If the variable "ibmcloud_api_key" is set in your provider,
51+
> you can initialize it using the following command
52+
> export TF_VAR_ibmcloud_api_key="Your IBM Cloud API Key"
53+
54+
1. Terraform must initialize the provider before it can be used.
55+
56+
```sh
57+
terraform init
58+
```
59+
60+
1. Review the plan
61+
62+
```sh
63+
terraform plan
64+
```
65+
66+
1. Start provisioning.
67+
68+
> Estimated duration: 45-60 mins
69+
70+
```sh
71+
terraform apply --var-file="odm.auto.tfvars"
72+
```
73+
74+
## Destroy Resources
75+
76+
1. Clean up the resources to avoid cost
77+
78+
```sh
79+
terraform destroy
80+
```

platform/roks/terraform/account-rg.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
##############################################################################
2+
# Create a resource group or reuse an existing one
3+
##############################################################################
4+
5+
variable "existing_resource_group_name" {
6+
default = ""
7+
description = "(Optional) Name of an existing resource group where to create resources"
8+
}
9+
10+
resource "ibm_resource_group" "group" {
11+
count = var.existing_resource_group_name != "" ? 0 : 1
12+
name = "${local.basename}-group"
13+
tags = var.tags
14+
}
15+
16+
data "ibm_resource_group" "group" {
17+
count = var.existing_resource_group_name != "" ? 1 : 0
18+
name = var.existing_resource_group_name
19+
}
20+
21+
locals {
22+
resource_group_id = var.existing_resource_group_name != "" ? data.ibm_resource_group.group.0.id : ibm_resource_group.group.0.id
23+
}
24+
25+
# output "resource_group_name" {
26+
# value = ibm_resource_group.group.name
27+
# }
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
2+
# OpenShift Variables
3+
##############################################################################
4+
5+
variable "openshift_cluster_name" {
6+
description = "Name of the cluster"
7+
type = string
8+
default = "roks"
9+
}
10+
11+
variable "openshift_version" {
12+
description = "The OpenShift version that you want to set up in your cluster."
13+
type = string
14+
default = ""
15+
}
16+
17+
variable "openshift_os" {
18+
description = "The Operating System (REDHAT_8_64 or RHCOS) for the Worker Nodes."
19+
type = string
20+
default = "RHCOS"
21+
}
22+
23+
variable "openshift_machine_flavor" {
24+
description = " The default flavor of the OpenShift worker node."
25+
type = string
26+
default = "bx2.4x16"
27+
}
28+
29+
variable "openshift_worker_nodes_per_zone" {
30+
description = "The number of worker nodes per zone in the default worker pool."
31+
type = number
32+
default = 1
33+
}
34+
35+
variable "worker_labels" {
36+
description = "Labels on all the workers in the default worker pool."
37+
type = map(any)
38+
default = null
39+
}
40+
41+
variable "openshift_wait_till" {
42+
description = "specify the stage when Terraform to mark the cluster creation as completed."
43+
type = string
44+
default = "OneWorkerNodeReady"
45+
46+
validation {
47+
error_message = "`openshift_wait_till` value must be one of `MasterNodeReady`, `OneWorkerNodeReady`, or `IngressReady`."
48+
condition = contains([
49+
"MasterNodeReady",
50+
"OneWorkerNodeReady",
51+
"IngressReady"
52+
], var.openshift_wait_till)
53+
}
54+
}
55+
56+
variable "openshift_disable_outbound_traffic_protection" {
57+
description = "Include this option to allow public outbound access from the cluster workers."
58+
type = bool
59+
default = true
60+
}
61+
62+
variable "openshift_disable_public_service_endpoint" {
63+
description = "Boolean value true if Public service endpoint to be disabled."
64+
type = bool
65+
default = false
66+
}
67+
68+
variable "openshift_force_delete_storage" {
69+
description = "force the removal of persistent storage associated with the cluster during cluster deletion."
70+
type = bool
71+
default = true
72+
}
73+
74+
variable "kms_config" {
75+
type = list(map(string))
76+
default = []
77+
}
78+
79+
variable "entitlement" {
80+
description = "Enable openshift entitlement during cluster creation ."
81+
type = string
82+
default = "cloud_pak"
83+
}
84+
85+
variable "openshift_update_all_workers" {
86+
description = "OpenShift version of the worker nodes is updated."
87+
type = bool
88+
default = true
89+
}
90+
91+
variable "is_openshift_cluster" {
92+
type = bool
93+
default = true
94+
}
95+
96+
variable "roks_worker_pools" {
97+
description = "List of maps describing worker pools"
98+
99+
type = list(object({
100+
pool_name = string
101+
machine_type = string
102+
workers_per_zone = number
103+
}))
104+
105+
default = [
106+
{
107+
pool_name = "dev"
108+
machine_type = "bx2.4x16"
109+
workers_per_zone = 1
110+
}
111+
]
112+
113+
validation {
114+
error_message = "Worker pool names must match the regex `^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$`."
115+
condition = length([
116+
for pool in var.roks_worker_pools :
117+
false if !can(regex("^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$", pool.pool_name))
118+
]) == 0
119+
}
120+
121+
validation {
122+
error_message = "Worker pools cannot have duplicate names."
123+
condition = length(distinct([
124+
for pool in var.roks_worker_pools :
125+
pool.pool_name
126+
])) == length(var.roks_worker_pools)
127+
}
128+
}
129+
130+
## Resources
131+
##############################################################################
132+
resource "ibm_container_vpc_cluster" "roks_cluster" {
133+
name = format("%s-%s", local.basename, var.openshift_cluster_name)
134+
vpc_id = ibm_is_vpc.vpc.id
135+
resource_group_id = local.resource_group_id
136+
# Optional: Specify OpenShift version. If not included, 4.15 is used
137+
kube_version = var.openshift_version == "" ? "4.15_openshift" : var.openshift_version
138+
operating_system = var.openshift_os
139+
cos_instance_crn = var.is_openshift_cluster ? ibm_resource_instance.cos_openshift_registry[0].id : null
140+
entitlement = var.entitlement
141+
force_delete_storage = var.openshift_force_delete_storage
142+
tags = var.tags
143+
update_all_workers = var.openshift_update_all_workers
144+
145+
flavor = var.openshift_machine_flavor
146+
worker_count = var.openshift_worker_nodes_per_zone
147+
wait_till = var.openshift_wait_till
148+
disable_public_service_endpoint = var.openshift_disable_public_service_endpoint
149+
# By default, public outbound access is blocked in OpenShift versions 4.15
150+
disable_outbound_traffic_protection = var.openshift_disable_outbound_traffic_protection
151+
152+
dynamic "zones" {
153+
for_each = { for subnet in ibm_is_subnet.subnet : subnet.id => subnet }
154+
content {
155+
name = zones.value.zone
156+
subnet_id = zones.value.id
157+
}
158+
}
159+
}
160+
161+
# Object Storage to backup the OpenShift Internal Registry
162+
##############################################################################
163+
resource "ibm_resource_instance" "cos_openshift_registry" {
164+
count = var.is_openshift_cluster ? 1 : 0
165+
name = join("-", [local.basename, "cos-registry"])
166+
resource_group_id = local.resource_group_id
167+
service = "cloud-object-storage"
168+
plan = "standard"
169+
location = "global"
170+
tags = var.tags
171+
}

0 commit comments

Comments
 (0)