Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Terraform with OpenTofu #606

Merged
merged 23 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ skip_list:
# Roles and modules imported from https://opendev.org/zuul/zuul-jobs
mock_roles:
- ensure-pip
- ensure-terraform
mock_modules:
- zuul_return
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
name: Check terraform syntax
name: Check opentofu syntax

"on":
push:
paths:
- 'terraform/**'
- '.github/workflows/check-terraform-syntax.yml'
- '.github/workflows/check-opentofu-syntax.yml'
pull_request:
paths:
- 'terraform/**'
- '.github/workflows/check-terraform.yml'
- '.github/workflows/check-opentofu-syntax.yml'

jobs:
check-terraform-syntax:
check-opentofu-syntax:
runs-on: ubuntu-latest

steps:
Expand All @@ -24,18 +24,18 @@ jobs:
- name: create credentials
run: cp secure.yaml.sample secure.yaml
working-directory: ./terraform
- name: Setup terraform
uses: hashicorp/setup-terraform@v2
- name: Setup OpenTofu
uses: opentofu/setup-opentofu@v1
with:
terraform_version: 1.4.6 # renovate: datasource=github-releases depName=hashicorp/terraform
- name: Terraform init
run: terraform init
tofu_version: 1.6.0 # renovate: datasource=github-releases depName=opentofu/opentofu
- name: Tofu init
run: tofu init
working-directory: ./terraform
- name: Terraform validate
run: terraform validate
- name: Tofu validate
run: tofu validate
working-directory: ./terraform
env:
ENVIRONMENT: gx-betacloud
- name: Terraform format
run: terraform fmt -check
- name: Tofu format
run: tofu fmt -check
working-directory: ./terraform
2 changes: 1 addition & 1 deletion doc/Upgrade-Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ on the cluster unless you have changed its configuration by tweaking
`cluster-template.yaml` (which you almost never do!) or `clusterctl.yaml`
(which you do often).

The other template file that changed -- however, some terraform logic is used to
The other template file that changed -- however, some opentofu logic is used to
prefill it with values. So you can't copy it from git.

##### R2 to R3
Expand Down
2 changes: 1 addition & 1 deletion doc/application-credentials.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Application Credentials

The terraform creates an [application credential](https://docs.openstack.org/keystone/wallaby/user/application_credentials.html) that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster.
OpenTofu creates an [application credential](https://docs.openstack.org/keystone/wallaby/user/application_credentials.html) that it passes into the created VM. This one is then used to authenticate the cluster API provider against the OpenStack API to allow it to create resources needed for the k8s cluster.

The AppCredential has a few advantages:

Expand Down
4 changes: 2 additions & 2 deletions doc/continuous-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ This section describes Zuul jobs defined within the k8s-cluster-api-provider pro
availability in Zuul worker node. Parent job also defines a Zuul semaphore `semaphore-openstack-access`,
that ensures that only one `openstack-access-base` job (or its children) can run at a time
- See a high level `k8s-cluster-api-provider-e2e-conformance` job steps:
- Pre-run playbook `dependencies.yaml` installs project prerequisites, e.g. terraform, yq, etc.
- Pre-run playbook `dependencies.yaml` installs project prerequisites, e.g. opentofu, yq, etc.
- Main playbook `e2e.yaml` spawns a k8s cluster, runs sonobuoy conformance test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts
- Cleanup-run playbook `cleanup.yaml` runs `ospurge`, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere

Expand All @@ -90,7 +90,7 @@ This section describes Zuul jobs defined within the k8s-cluster-api-provider pro
availability in Zuul worker node. Parent job also defines a Zuul semaphore `semaphore-openstack-access`,
that ensures that only one `openstack-access-base` job (or its children) can run at a time
- See a high level `k8s-cluster-api-provider-e2e-quick` job steps:
- Pre-run playbook `dependencies.yaml` installs project prerequisites, e.g. terraform, yq, etc.
- Pre-run playbook `dependencies.yaml` installs project prerequisites, e.g. opentofu, yq, etc.
- Main playbook `e2e.yaml` spawns a k8s cluster, runs sonobuoy quick test, and cleans created infrastructure, all by k8s-cluster-api-provider scripts
- Cleanup-run playbook `cleanup.yaml` runs `ospurge`, cleanup created application credentials and keypair to ensure that multiple e2e runs do not interfere

Expand Down
26 changes: 13 additions & 13 deletions doc/make-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ This will deploy the [cluster-stack-operator](https://github.com/SovereignCloudS
### Make clean

``make clean`` does ssh to the capi management server to clean up the created clusters prior
to terraform cleaning up the resources it has created. This is sometimes insufficient to clean up
to opentofu cleaning up the resources it has created. This is sometimes insufficient to clean up
unfortunately, some error in the deployment may result in resources left around.

### Make fullclean

``make fullclean`` uses a custom script `cleanup/cleanup.sh` (using the openstack CLI) to clean up
everything while trying to not hit any resources not created by the CAPI or terraform for
everything while trying to not hit any resources not created by the CAPI or opentofu for
clusters from this management host.
It is the recommended way for doing cleanups if ``make clean`` fails. Watch out for leftover
floating IP addresses and persistent volumes, as these can not be easily traced back to the
Expand All @@ -105,7 +105,7 @@ case we don't need the force options.

You can purge the whole project via ``make purge``. Be careful with that command as it will purge
*all resources in the OpenStack project* even those that have not been created through this
Terraform script or the Cluster API.
OpenTofu script or the Cluster API.
It requires the [``ospurge``](https://opendev.org/x/ospurge) tool.
Install it with ``python3 -m pip install git+https://git.openstack.org/openstack/ospurge``.

Expand Down Expand Up @@ -145,52 +145,52 @@ This will run tests of the configuration on testcluster using sonobuoy of the st

This will run tests of the configuration on testcluster using sonobuoy of the CSI.

## Terraform commands
## OpenTofu commands

### make init

``make init``

This will initialize terraform. It will download the required providers and modules.
This will initialize opentofu. It will download the required providers and modules.
It will also select or create a new workspace for you. The workspace name is the same as the
``ENVIROMENT`` variable.

### make attach

``make attach RESOURCE=<resource-id> PARAMS=...``

This will attach a resource to the terraform state. This is useful if you have created a resource outside of terraform
and want to manage it with terraform.
This will attach a resource to the opentofu state. This is useful if you have created a resource outside of opentofu
and want to manage it with opentofu.

### make detach

``make detach RESOURCE=<resource-id> PARAMS=...``

This will detach a resource from the terraform state. This is useful if you have changed a resource outside of terraform
or you no longer want to manage it with terraform.
This will detach a resource from the opentofu state. This is useful if you have changed a resource outside of opentofu
or you no longer want to manage it with opentofu.

### make state-push

``make state-push``

This will push the terraform state to specified storage if set. This is useful if you don't want to store the state
This will push the opentofu state to specified storage if set. This is useful if you don't want to store the state
locally.

### make dry-run

``make dry-run``

This will run a dry-run of the terraform apply command. This is useful if you want to see what terraform will do before
This will run a dry-run of the opentofu apply command. This is useful if you want to see what opentofu will do before
actually doing it.

### make show

``make show``

This will show the terraform state. This is useful if you want to see what terraform is managing.
This will show the opentofu state. This is useful if you want to see what opentofu is managing.

### make list

``make list``

This will list all the resources managed by terraform. This is useful if you want to see what terraform is managing.
This will list all the resources managed by opentofu. This is useful if you want to see what opentofu is managing.
2 changes: 1 addition & 1 deletion doc/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ Once we as the SCS Community have the gitops style cluster control working, the

The provided solution covers the following two main topics:

1. Automation (terraform, Makefile) to bootstrap a cluster-API management server by installing kind on a vanilla Ubuntu image and deploying some tools on this node ([kubectl](https://kubernetes.io/docs/reference/kubectl/overview/), [openstack CLI tools](https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html), [k9s](https://github.com/derailed/k9s), [cilium](https://cilium.io/), [calico](https://www.tigera.io/tigera-products/calico/), [helm](https://helm.sh/), [flux](https://fluxcd.io/) ...) and deploying [cluster-API](https://cluster-api.sigs.k8s.io/) (clusterctl) and the [OpenStack cluster-api provider](https://github.com/kubernetes-sigs/cluster-api-provider-openstack) along with suitable credentials. The terraform automation is driven by a Makefile for convenience. The tooling also contains all the logic to clean up again. The newly deployed node clones this git repository early in the bootstrap process and uses the thus received files to set up the management cluster and scripts.
1. Automation (opentofu, Makefile) to bootstrap a cluster-API management server by installing kind on a vanilla Ubuntu image and deploying some tools on this node ([kubectl](https://kubernetes.io/docs/reference/kubectl/overview/), [openstack CLI tools](https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html), [k9s](https://github.com/derailed/k9s), [cilium](https://cilium.io/), [calico](https://www.tigera.io/tigera-products/calico/), [helm](https://helm.sh/), [flux](https://fluxcd.io/) ...) and deploying [cluster-API](https://cluster-api.sigs.k8s.io/) (clusterctl) and the [OpenStack cluster-api provider](https://github.com/kubernetes-sigs/cluster-api-provider-openstack) along with suitable credentials. The opentofu automation is driven by a Makefile for convenience. The tooling also contains all the logic to clean up again. The newly deployed node clones this git repository early in the bootstrap process and uses the thus received files to set up the management cluster and scripts.

2. This node can be connected to via ssh and the deployed scripts there can be used to manage workload clusters and then deploy various standardized tools (such as e.g. [OpenStack Cloud Controller Manager](https://github.com/kubernetes/cloud-provider-openstack)(OCCM), [cinder CSI](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/cinder-csi-plugin/using-cinder-csi-plugin.md), calico or cilium CNI, [nginx ingress controller](https://kubernetes.github.io/ingress-nginx/), [cert-manager](https://cert-manager.io/), ...) and run tests (e.g. CNCF conformance with [sonobuoy](https://sonobuoy.io/)). The tools and artifacts can be updated via `git pull` at any time and the updated settings rolled out to the workload clusters. Note that the script collection will eventually be superseded by the [capi-helm-charts](https://github.com/stackhpc/capi-helm-charts). The medium-term goal is to actually create a reconciliation loop here that would perform life-cycle-management for clusters according to the cluster configuration stored in an enhanced [cluster-api style](https://cluster-api.sigs.k8s.io/clusterctl/configuration.html) clusterctl.yaml from git repositories and thus allow a pure [gitops](https://www.weave.works/technologies/gitops/) style cluster management without ever ssh'ing to the management server.
2 changes: 1 addition & 1 deletion doc/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ via [cluster-api](https://cluster-api.sigs.k8s.io/)(CAPI).

- make
- kubectl
- terraform
- opentofu
- yq
- python3-openstackclient, python3-octaviaclient

Expand Down
4 changes: 2 additions & 2 deletions doc/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Linux/MacOS/WSL laptop.
Requirements for the deployment host:

- You need to have installed:
- Terraform (<https://learn.hashicorp.com/tutorials/terraform/install-cli>).
- OpenTofu (<https://opentofu.org/docs/intro/install/>).
- `yq` (python3-yq or yq snap)
- GNU make
- openstack (python3-openstackclient) and plugin for octavia (python3-octaviaclient) Via pip or your distribution.
*Needed only in case you want to clean the management server or interact with openstack directly.*
- You must have credentials to access the cloud. Terraform will look for `clouds.yaml` and optionally `secure.yaml` in
- You must have credentials to access the cloud. OpenTofu will look for `clouds.yaml` and optionally `secure.yaml` in
the current working directory (`terraform`), in `~/.config/openstack/` or `/etc/openstack` (in this order), just like
the [openstack client](https://docs.openstack.org/python-openstackclient/latest/configuration/index.html#clouds-yaml).
- The API endpoints of the OpenStack cloud should have a certificate signed by a trusted CA. (Self-signed or custom CAs
Expand Down
8 changes: 4 additions & 4 deletions doc/usage/containter-registry-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This feature could be useful in various uses cases, e.g.:
SCS KaaS reference implementation allows users to pass container registry host config
files to configure containerd. Containerd configuration is applied cluster wide as it
is CRI used in SCS KaaS clusters. Additional registry host config files for containerd
could be passed through the `containerd_registry_files` terraform variable. This variable
could be passed through the `containerd_registry_files` opentofu variable. This variable
expects an object with two attributes:

- `hosts` attribute defines additional registry host config files for containerd.
Expand All @@ -33,11 +33,11 @@ The default value of the `containerd_registry_files` variable instructs containe
container registry, see related
issue [#417](https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/417).
The host config file used as a default is
defined [here](https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/1b6ef9d4c64c94bc77144a072e0309d484de54be/terraform/files/containerd/docker.io).
defined [here](https://github.com/SovereignCloudStack/k8s-cluster-api-provider/blob/main/terraform/files/containerd/docker.io).
This should prevent issues with pull rate limiting from DockerHub public container registry,
e.g. [#414](https://github.com/SovereignCloudStack/k8s-cluster-api-provider/issues/414).

The above default value could be overridden using any techniques that Terraform allows, e.g.
The above default value could be overridden using any techniques that OpenTofu allows, e.g.
via environment variable:

```bash
Expand Down Expand Up @@ -80,7 +80,7 @@ upgrade existing environments (workload clusters) with stable releases which are
tested.

This tutorial instructs (advanced) users what needs to be done on the cluster management
instance without re-deploying it via Terraform. Patches described in this tutorial
instance without re-deploying it via OpenTofu. Patches described in this tutorial
modify existing environment with changes that have been developed within "containerd registry"-related PRs:
- PR#432
- PR#447
Expand Down
2 changes: 1 addition & 1 deletion doc/usage/custom-ca.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Here the file `ca-bundle.pem` contains custom root CA and potentially intermedia
Steps of what happens with the custom cacert in k8s-cluster-api-provider:
1. `cacert` setting is provided inside clouds.yaml
2. Cacert file referenced by `cacert` key (1.) is copied to the management server
directory `~/cluster-defaults/${cloud_provider}-cacert` by Terraform
directory `~/cluster-defaults/${cloud_provider}-cacert` by OpenTofu
3. During the management server bootstrap process cacert is injected to
the *~/cluster-defaults/cluster-template.yaml* to *KubeadmControlPlane* and *KubeadmConfigTemplate* files
as file with cacert content from already defined secret *${CLUSTER_NAME}-cloud-config* and will be later
Expand Down
2 changes: 1 addition & 1 deletion doc/usage/harbor.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Project [k8s-harbor](https://github.com/SovereignCloudStack/k8s-harbor) is used
container registry deployment https://registry.scs.community/.

With this project, it is possible to deploy Harbor in a similar way into the workload cluster.
If you want to deploy Harbor, set terraform variable `deploy_harbor = true`. It will deploy
If you want to deploy Harbor, set opentofu variable `deploy_harbor = true`. It will deploy
Harbor with [default options](#default-deployment). The recommended approach is to
set up also [persistence](#persistence) and [ingress with tls](#ingress-and-tls).

Expand Down
55 changes: 48 additions & 7 deletions playbooks/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
kubectl_version: "1.28.1"
openstackclient_version: "6.2.0"
octaviaclient_version: "3.4.0"
tf_version: "1.4.6"
opentofu_version: "1.6.0"
install_dir: "{{ ansible_user_dir }}/.local/bin"
environment:
PATH: "{{ install_dir }}:{{ ansible_env.PATH }}"
roles:
- role: ensure-pip # https://zuul-ci.org/docs/zuul-jobs/latest/python-roles.html#role-ensure-pip
- role: ensure-terraform # https://zuul-ci.org/docs/zuul-jobs/latest/hashicorp-roles.html#role-ensure-terraform
vars:
terraform_version: "{{ tf_version }}"
terraform_install_dir: "{{ install_dir }}"
tasks:
- name: Make sure installation directory exists
ansible.builtin.file:
path: "{{ install_dir }}"
state: directory
mode: 0755
- name: Install jq
ansible.builtin.get_url:
url: "https://github.com/jqlang/jq/releases/download/jq-{{ jq_version }}/jq-linux64"
Expand All @@ -44,6 +45,46 @@
extra_args: --user
- name: Install ip command
ansible.builtin.package:
name:
- iproute2
name: iproute2
become: true
- name: Install OpenTofu
# TODO: write separate role ensure-opentofu, see https://opendev.org/zuul/zuul-jobs/src/branch/master/roles/ensure-terraform
block:
- name: Install unzip
ansible.builtin.package:
name: unzip
become: true
- name: Create temp directory
ansible.builtin.tempfile:
state: directory
register: tofu_install_tempdir
- name: Download OpenTofu archive
ansible.builtin.get_url:
url: "https://github.com/opentofu/opentofu/releases/download/v{{ opentofu_version }}/tofu_{{ opentofu_version }}_linux_amd64.zip"
dest: "{{ tofu_install_tempdir.path }}/opentofu.zip"
mode: 0644
# TODO: checksum
- name: Create OpenTofu package directory
ansible.builtin.file:
path: "{{ tofu_install_tempdir.path }}/opentofu"
state: directory
mode: 0755
- name: Unarchive OpenTofu
ansible.builtin.unarchive:
src: "{{ tofu_install_tempdir.path }}/opentofu.zip"
dest: "{{ tofu_install_tempdir.path }}/opentofu"
remote_src: true
- name: Install OpenTofu
ansible.builtin.copy:
src: "{{ tofu_install_tempdir.path }}/opentofu/tofu"
dest: "{{ install_dir }}/tofu"
mode: "+x"
remote_src: true
- name: Remove temp directory
ansible.builtin.file:
path: "{{ tofu_install_tempdir }}"
state: absent
- name: Output OpenTofu version
ansible.builtin.command: "tofu version"
register: tofu_version
changed_when: tofu_version.rc != 0
2 changes: 1 addition & 1 deletion playbooks/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
executable: /bin/bash
register: mtu
changed_when: false
- name: Set mtu for the default interface # workaround for terraform file provisioner scp error
- name: Set mtu for the default interface # workaround for opentofu file provisioner scp error
ansible.builtin.command: "ip link set {{ dev.stdout }} mtu 1500"
become: true
when: mtu.stdout != "1500"
Expand Down
Loading
Loading