Skip to content
Snippets Groups Projects
Unverified Commit 93aee30a authored by Marco Emilio "sphakka" Poleggi's avatar Marco Emilio "sphakka" Poleggi
Browse files

Added tasks 9 and 10

parent fa66b958
Branches
Tags
No related merge requests found
...@@ -721,7 +721,9 @@ unless the correct [user-data merge strategy is ...@@ -721,7 +721,9 @@ unless the correct [user-data merge strategy is
specified](https://cloudinit.readthedocs.io/en/latest/reference/merging.html). specified](https://cloudinit.readthedocs.io/en/latest/reference/merging.html).
### Task #9: Provisioning KinD with with Terraform ### ### Task #9: Provisioning KinD with Cloud-init ###
**Goal:** provision an application software stack with Terraform and Cloud-init.
**Please, complete the [K8s Lab **Please, complete the [K8s Lab
tutorial](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-k8s) tutorial](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-k8s)
...@@ -748,3 +750,126 @@ on the instance as done during the K8s Lab: ...@@ -748,3 +750,126 @@ on the instance as done during the K8s Lab:
1. Write a minimal KinD configuration file for 2 worker nodes. 1. Write a minimal KinD configuration file for 2 worker nodes.
1. Provision the cluster. 1. Provision the cluster.
1. Deploy the matallb load balancer service. 1. Deploy the matallb load balancer service.
### Task #10: Handling Kubernetes deployments ###
**Goal:** deploy a Kubernetes-based micro-service application with Terraform
and KinD.
So far, we have seen how to provision a minimal infrastructure an install a
K8s/KinD SW stack. Now, the main issue with KinD is that it's not designed to
be remotely controlled, which complicates service deployment operations:
indeed, Terraform is normally installed and called from a workstation. There
are two possibilities:
a. Use TF's special *resource-less provisioners* within the same TF plan to
spawn operations on the target infrastructure after its provisioning.
a. Use TF's official Kubernetes provider with an auxiliary TF plan
exploiting and SSH tunnel to the instance, after its provisioning by the
main TF plan.
#### Task #10.1 Resource-less provisioning ####
The TF [resource-less
provisioner](https://developer.hashicorp.com/terraform/language/resources/provisioners/null_resource)
approach is considered "last-resort", because it is not very flexible and
can't easily implement the *desired state* paradigm. Indeed, some other
configuration management solutions, like Ansible, are surely better suited for
this task. Nonetheless, it is interesting in its capability of handling
generic operations.
We have seen that a TF *resource* is an entity backed up by a *provider*, that
is, a mechanism that processes the resource declaration and invokes a given
provisioning API. Terraform provides also special resources, not bound to any
provider (no backend API), which can be used to encapsulate provisioners for
local or remote operations.
In our case, the workflow, implemented within the same TF plan, is the the
following:
1. Provision an instance with the OpenStack provider.
1. Provision extra system configuration and packages with Cloud-init.
1. Provision, or rather deploy, a K8s service via `file` and `remote-exec`
provisioners.
You shall extend your `main.tf` plan recipe with:
1. At least one `terraform_data` resource declaration that encapsulate all the service
deployment logic: transferring files and sending commands.
1. Inside your `terraform_data` declaration:
- a [`connection`
block](https://developer.hashicorp.com/terraform/language/resources/provisioners/connection)
of type SSH with the credentials of the user `terraform` as defined in
one of the tasks above;
- as many [file provisioner](https://developer.hashicorp.com/terraform/language/resources/provisioners/file) blocks as needed to transfer the KinD and
MetalLB confguration and deployment files;
- at least one [remote-exec
provisioner](https://developer.hashicorp.com/terraform/language/resources/provisioners/remote-exec)
which implements a script of shell commands to move around files, create
a KinD cluster and, finally, deploy your MetalLB service as done in [Lab K8s](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-k8s/-/blob/main/README.md#part-5-actually-deploying-an-application).
The solution might be something like:
``` hcl
resource "terraform_data" "kind_cluster" {
connection {
type = "ssh"
user = ...
private_key = ...
host = ...
}
provisioner "file" {
source = ...
destination = ...
}
provisioner "file" {
...
}
provisioner "remote-exec" {
inline = [
"shell command",
...,
]
}
}
```
:bulb: Please mind that:
- The provisioner blocks are processed in the order of appearance.
- For a maximum of flexibility, it is advisable to write 2
`terraform_data` blocks: one for KinD and another for MetalLB. This way you
can test the creation of the two resources separately.
:warning: You will probably hit some thorny issues:
- Depending on how you code the `terraform_data` block(s), the resource(s)
might get processed too soon or in the wrong order. So, be sure of using
*variable references* so as to induce indirect dependencies. You might also
need to explicitly declare a `depends_on` list.
- Before doing anything, you must wait for Cloud-init to finish its tasks:
this can take several minutes (at least 4-5).
- KinD and K8s are very complex and, during set up, might fail in unexpected
ways, chiefly because of system/network issues. Thus, it is wise to wait a
bit (at least 20-30 seconds) after each `kind/kubectl` command.
#### Task #10.2 Auxiliary K8s plan provisioning ####
:warning: **Under construction!**
As you have you seen, the resource-less provisioning approach is ridden with
pitfalls. A better, more programmatic way is to employ an auxiliary TF plan
based on the [official TF Kubernetes
provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs)
and exploit an [SSH tunnel to convey K8s API
calls](https://gitedu.hesge.ch/lsds/teaching/bachelor/cloud-and-deployment/lab-k8s/-/blob/main/README.md#controlling-your-cluster-from-a-remote-console)
to the remote KinD instance.
...@@ -40,13 +40,26 @@ resource "openstack_compute_instance_v2" "app_server" { ...@@ -40,13 +40,26 @@ resource "openstack_compute_instance_v2" "app_server" {
# Option #3 (*preferred*). Cloud-init with user data. Access with user # Option #3 (*preferred*). Cloud-init with user data. Access with user
# specified in the cloud-init YAML file. Key pair is not visible in Horizon # specified in the cloud-init YAML file. Key pair is not visible in Horizon
# @@ KEY PAIR CONFIGURATION @@ # @@ CLOUD-INIT: KEY PAIR CONFIGURATION @@
# @Task #8.1
# @@ CLOUD-INIT: DEFAULT USER CONFIGURATION @@
# @Task #9.1
# @@ CLOUD-INIT: KIND PROVISIONING @@
} }
# @Task #7. Network configuration.
# @Task #7. Network configuration.
# @@ SEC GROUP CONFIGURATION @@ # @@ SEC GROUP CONFIGURATION @@
# @@ SEC GROUP RULES CONFIGURATION: ICMP, TCP/22 @@ # @@ SEC GROUP RULES CONFIGURATION: ICMP, TCP/22 @@
# @@ FIP + PORT + ASSOCIATION CONFIGURATION @@ # @@ FIP + PORT + ASSOCIATION CONFIGURATION @@
# @Task #8.2
# @@ INTEGRATE CLOUD-INIT WITH TERRAFORM @@
# @Task #10.1
# @@ KIND/K8S SERVICE DEPLOYMENT BY RESOURCE-LESS PROVISIONING @@
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment