From 4da0a4d25906fc77a93aa410a2af52383d26690f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ing=2E=20Kl=C3=A1ra=20Moravcov=C3=A1?=
 <klara.moravcova@cesnet.cz>
Date: Thu, 25 Apr 2024 10:48:07 +0200
Subject: [PATCH] Add support for S3 backend.

---
 README.md                     | 40 +++++++++++----------------
 terraform/.gitignore          |  4 ++-
 terraform/init.sh             | 51 +++++++++++++++++++++++++++++++++++
 terraform/main.tf             |  2 +-
 terraform/openstack_vars.yaml |  3 ---
 5 files changed, 71 insertions(+), 29 deletions(-)
 create mode 100755 terraform/init.sh
 delete mode 100644 terraform/openstack_vars.yaml

diff --git a/README.md b/README.md
index a8ef708..768c1d2 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,11 @@
 ## Prerequisites:
-- terraform - [install](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)</br>
-- Form to access group project - https://projects.cloud.muni.cz/
+- terraform - [install](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)
+- openstack-cli - [install](https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html)
+- Form to access group project - https://projects.cloud.muni.cz/ (for master nodes we recommend to ask for `hpc.8core-16ram` )
 
 ## Create Infrastructure
 
-Create openstack application credentials: </br>
+Create openstack application credentials: 
  - On tab Identity > application credentials
  - \+ create application credential
  - Give a name > Create Applicaiton Credential
@@ -13,58 +14,49 @@ Create openstack application credentials: </br>
 ```
 git clone git@gitlab.ics.muni.cz:cloud/kubernetes/kubernetes-infra-example.git
 ```
-If required you may change the values as needed. (like infrastructure name, cluster size (master nodes, worker nodes groups), etc.)</br>
-- <code>~/kubernetes-infra-example/terraform/main.tf</code>
-- Give a path to your public ssh key at: <code>ssh_public_key = "~/.ssh/id_rsa.pub"</code>
+If required you may change the values as needed. (like infrastructure name, cluster size (master nodes, worker nodes groups), etc.) 
+- `~/kubernetes-infra-example/terraform/main.tf`
+- Give a path to your public ssh key at: `ssh_public_key = "~/.ssh/id_rsa.pub"`
 
 ```
 cd ~/kubernetes-infra-example/terraform/
-terraform init
 source ~/path/to/credentials.sh
+./init.sh
+terraform init
 terraform apply
 ```
 
 ## Create Kubernetes Cluster
 
-- <code>cd ~/kubernetes-infra-example/ansible/group_vars/all/</code>
+- `cd ~/kubernetes-infra-example/ansible/group_vars/all/`
 - All possible group vars are in [Kubespray](https://github.com/kubernetes-sigs/kubespray) project.
-- In <code>openstack.yml</code> modify the application credentials, can be the same credentials as already created.
+- In `openstack.yml` modify the application credentials, can be the same credentials as already created.
 
 
 #### Install Kubernetes
-Prerequisites: </br>
+Prerequisites: 
 ```
 cd ~/kubernetes-infra-example/ansible/01-playbook/
 sudo pip install -r requirements.txt
 ansible-galaxy install -r requirements.yml
 ```
 
-Run ansible playbook: </br>
+Run ansible playbook:
 ```
 cd ~/kubernetes-infra-example/ansible/01-playbook/
 ansible-playbook -i ../ansible_inventory --user=ubuntu --become --become-user=root play.yml
 ```
 
 #### Access via config
-- Kubeconfig is located in the artifacts directory, you can copy the config file to <code>~/.kube</code> directory for local access.
+- Kubeconfig is located in the artifacts directory, you can copy the config file to `~/.kube` directory for local access.
 
-#### Access with SSH </br>
+#### Access with SSH
 - If you need to access the cluster
-- Bastion ansible_hosts at <code>~/kubernetes-infra-example/ansible/ansible_inventory</code>
+- Bastion ansible_hosts at `~/kubernetes-infra-example/ansible/ansible_inventory`
 ```
 ssh -J ubuntu@<bastion_ip_address> ubuntu@<control-node_ip_address>
 # For example:
 # ssh -J ubuntu@195.113.167.169 ubuntu@10.10.10.26
 sudo -i
 kubectl get nodes
-```
-#### Nginx Ingress Controller
-Prerequisites: </br>
-- helm - [install](https://helm.sh/docs/intro/install/)</br>
-
-```
-helm repo add nginx-stable https://helm.nginx.com/stable
-helm repo update
-helm install nginx-ingress nginx-stable/nginx-ingress --set rbac.create=true
-kubectl get service
 ```
\ No newline at end of file
diff --git a/terraform/.gitignore b/terraform/.gitignore
index 3e352d0..e973e7c 100644
--- a/terraform/.gitignore
+++ b/terraform/.gitignore
@@ -10,4 +10,6 @@ crash.log
 
 plan
 plan1
-.terraform.lock.hcl
\ No newline at end of file
+.terraform.lock.hcl
+.tf-s3-creds
+backend.tf
\ No newline at end of file
diff --git a/terraform/init.sh b/terraform/init.sh
new file mode 100755
index 0000000..9c58950
--- /dev/null
+++ b/terraform/init.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+PROJECT_NAME=$(openstack application credential show ${OS_APPLICATION_CREDENTIAL_ID} -f value -c name)
+INFRA_NAME=$(grep -oP 'infra_name\s*=\s*"\K[^"]+' main.tf | awk '{print $1}')
+# Check if the container already exists
+if openstack container show "$PROJECT_NAME-$INFRA_NAME-tf-backend" >/dev/null 2>&1; then
+    echo "Container already exists, skipping creation."
+else
+    # Container doesn't exist, create it
+    openstack container create "$PROJECT_NAME-$INFRA_NAME-tf-backend"
+    echo "Container created."
+fi
+# Check if EC2 credentials already exist
+existing_credentials=$(openstack ec2 credentials list -f value | grep -c '^')
+if [ "$existing_credentials" -gt 0 ]; then
+    access=$(openstack ec2 credentials list -f value | head -n 1 |  awk '{print $1}')
+    secret=$(openstack ec2 credentials list -f value | head -n 1 |  awk '{print $2}')
+    echo "EC2 credentials already exist, skipping creation."
+else
+    # Create new EC2 credentials
+    CREDENTIALS=$(openstack ec2 credentials create -f shell)
+    access=$(echo "$CREDENTIALS" | grep -o 'access="[^"]*"' | cut -d'"' -f2)
+    secret=$(echo "$CREDENTIALS" | grep -o 'secret="[^"]*"' | cut -d'"' -f2)
+    echo "EC2 credentials created."
+fi
+if [ -f ".tf-s3-creds" ]; then
+    echo "Credential file already exists, skipping creation."
+else
+    cat > .tf-s3-creds << EOL
+    [default]
+    aws_access_key_id=${access}
+    aws_secret_access_key=${secret}
+EOL
+    echo "Credential file created."
+fi
+cat > backend.tf << EOL
+ terraform { 
+  backend "s3" {
+    endpoints =                 { s3 = "https://object-store.cloud.muni.cz/"}
+    shared_credentials_files    = ["./.tf-s3-creds"]
+    bucket                      = "$PROJECT_NAME-$INFRA_NAME-tf-backend"
+    use_path_style              = true
+    key                         = "terraform.tfstate"
+    region                      = "brno1"
+    skip_credentials_validation = true
+    skip_region_validation      = true
+    skip_requesting_account_id  = true
+    skip_metadata_api_check     = true
+    skip_s3_checksum            = true
+  }
+} 
+EOL
\ No newline at end of file
diff --git a/terraform/main.tf b/terraform/main.tf
index 92552d9..5002c43 100644
--- a/terraform/main.tf
+++ b/terraform/main.tf
@@ -1,7 +1,7 @@
 module "kubernetes_infra" {
 
   #  source = "./../../kubernetes-infra"
-    source = "git::https://gitlab.ics.muni.cz/cloud/terraform/modules/kubernetes-infra.git?ref=2.0.0"
+    source = "git::https://gitlab.ics.muni.cz/cloud/terraform/modules/kubernetes-infra.git?ref=2.0.1"
 
   # Example of variable override
   ssh_public_key = "~/.ssh/id_rsa.pub"
diff --git a/terraform/openstack_vars.yaml b/terraform/openstack_vars.yaml
deleted file mode 100644
index 0036128..0000000
--- a/terraform/openstack_vars.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-external_openstack_lbaas_floating_network_id: 9edb9ab8-8742-49e3-9461-528f31397672
-external_openstack_lbaas_network_id: 60bfbe57-ae9f-4455-b606-ae08062c3d16
-external_openstack_lbaas_subnet_id: 17b23236-4391-46e3-8ba4-be86d43d4034
-- 
GitLab