Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 51 additions & 0 deletions .github/workflows/server-terraform-tags.yml
Comment thread
rene-oromtz marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Create version tag for testflinger server terraform module
permissions:
contents: read
on:
push:
branches:
- main
paths:
- server/terraform/**

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
auto-tag-terraform-module:
name: Create version tag for the terraform module
runs-on: ubuntu-latest
permissions:
contents: write # necessary for writing tag

steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0 # necessary for semantic versioning
filter: blob:none # exclude file contents for faster checkout
persist-credentials: true # necessary for pushing tags

- name: Generate semantic version
id: version
uses: PaulHatch/semantic-version@f29500c9d60a99ed5168e39ee367e0976884c46e # v6.0.1
with:
tag_prefix: "testflinger-k8s-"
major_pattern: "breaking(terraform-server):"
minor_pattern: "feat(terraform-server):"
change_path: "server/terraform/"
search_commit_body: true
enable_prerelease_mode: false

- name: Create and push tag
env:
TAG: ${{ steps.version.outputs.version_tag }}
run: |
echo ::group::Create tag
git tag "$TAG"
echo ::endgroup::
echo ::notice::"$TAG"
echo ::group::Push tag
git push origin $TAG
echo ::endgroup::
169 changes: 169 additions & 0 deletions server/terraform/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Contributing to Testflinger Terraform modules

This document outlines contribution guidelines specific to the Testflinger Server
Terraform module.

To learn more about the general contribution guidelines for the Testflinger project,
refer to the [Testflinger contribution guide](../../CONTRIBUTING.md).

## Pull Requests

Any change to the terraform modules should be semantically versioned, for automation
to automatically tag your commits, you should consider the following patterns:
- `breaking(terraform-server):` - Creates a major release
- `feat(terraform-server):` - Creates a minor release

By default, any commit without the above patterns will create a patch version bump.
Refer to [Terraform versioning guide][versioning-guide] to understand more about
semantic versioning Terraform modules.

## Testflinger Server Terraform Deployment

The following instructions are meant to provide developers a guide on how to
deploy a Testflinger Server by using [Terraform].

### Set up a Juju environment

It is recommended to install the pre-requisites on a VM rather than your host
machine. To do so, first install [Multipass]:

```shell
sudo snap install multipass
```

Then launch a new VM instance (this may take a while):

```shell
multipass launch noble --disk 50G --memory 4G --cpus 2 --name testflinger-juju --mount /path/to/testflinger:/home/ubuntu/testflinger --cloud-init /path/to/testflinger/server/terraform/dev/cloud-init.yaml --timeout 1200
```

Feel free to increase the storage, memory, CPU, or VM name.

> [!NOTE]
> The initialization may time out. That's fine as long as the setup actually completes.
> You can tell that the setup completed by checking if the Juju models were created.

Check that the models were created:

```shell
multipass exec testflinger-juju -- juju models
```

### Initialize project's terraform

Now that everything has been set up, you can initialize the project's terraform.
The following guide setups a higher-level module to configure the Testflinger
Server Charm deployment.

Change your directory on your host machine to the terraform dev directory:

```shell
cd /path/to/testflinger/server/terraform/dev
```

Then run:

```shell
multipass exec testflinger-juju -- terraform init
```

### Set up variables

Refer to the [README](README.md#api) for the full list of required variables.

The `terraform/dev` directory has sensitive values to be provided before
deployment. Create a `terraform.tfvars` file inside `terraform/dev` with the
following secrets:

```hcl
jwt_signing_key = "<your-jwt-signing-key>"
testflinger_secrets_master_key = "<your-secrets-master-key>"
```


> [!NOTE]
> Only `jwt_signing_key` is required. In case `terraform.tfvars` is not provided
> terraform will prompt for the value.

> [!WARNING]
> Never commit `terraform.tfvars` to version control. The file is excluded via
> `.gitignore` for this reason.

### Deploy

In the terraform directory on your host machine, run:

```shell
multipass exec testflinger-juju -- terraform apply -auto-approve
```

Then wait for the deployment to settle and all the statuses to become active.
You can watch the statuses via:

```shell
multipass exec testflinger-juju -- juju status --storage --relations --watch 5s
```

### Connect to your deployment

Look at the IPv4 addresses of your testflinger-juju VM through:

```shell
multipass info testflinger-juju
```

One of these connects to the ingress enabled inside the VM. To figure out which one,
try the following command on each IP address until you get a response:

```shell
curl --connect-to ::<ip-address> http://testflinger.local/v1
```

Once you find the IP address, add the following entry to your host machine's
`/etc/hosts` file:

```text
<ip-address> testflinger.local
```

After that you should be able to reach the Testflinger frontend on your host
machine's browser through `http://testflinger.local`. You should also be able
to access the API through `http://testflinger.local/v1/`.

### Teardown

To take everything down, you can start with terraform:

```shell
multipass exec testflinger-juju -- terraform destroy -auto-approve
```

The above step can take a while and may even get stuck with some applications
in error state. You can watch it through:

```shell
multipass exec testflinger-juju -- juju status --storage --relations --watch 5s
```

To forcefully remove applications stuck in error state:

```shell
multipass exec testflinger-juju -- juju remove-application <application-name> --destroy-storage --force
```

Once everything is down and the juju model has been deleted you can stop the
multipass VM:

```shell
multipass stop testflinger-juju
```

Optionally, delete the VM:

```shell
multipass delete --purge testflinger-juju
```

[Multipass]: https://canonical.com/multipass
[Terraform]: https://developer.hashicorp.com/terraform
[versioning-guide]: https://developer.hashicorp.com/terraform/plugin/best-practices/versioning
146 changes: 61 additions & 85 deletions server/terraform/README.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,79 @@
# Juju deployment
Comment thread
ajzobro marked this conversation as resolved.
# Terraform module for Testflinger Server

Local Juju and charm deployment via microk8s and terraform.
This is a Terraform module facilitating the deployment of the Testflinger Server
charm, using the [Terraform Juju provider][juju-provider]. For more information,
refer to the provider [documentation][juju-provider-docs].

## Setup a juju environment
## Requirements

It is recommended to install the pre-requisites on a VM rather than your host machine. To do so, first install multipass:
This module requires a Juju model UUID to be available. Refer to the [usage section](#usage)
below for more details.

```bash
sudo snap install multipass
```
## API

Then launch a new VM instance using (this will take a while):
### Inputs

```bash
multipass launch noble --disk 50G --memory 4G --cpus 2 --name testflinger-juju --mount /path/to/testflinger:/home/ubuntu/testflinger --cloud-init /path/to/testflinger/server/terraform/cloud-init.yaml --timeout 1200
```
The module offers the following configurable inputs:

Feel free to increase the storage, memory, cpu limits or change the VM name.
| Name | Type | Description | Required |
| - | - | - | - |
| `app_name` | string | Name of the Testflinger server application | False |
| `base` | string | Operating system base to use for the Testflinger server charm | False |
| `channel` | string | Channel to use for the charm | False |
| `config` | map(string) | Map of charm config options | False |
| `constraints` | string | Constraints to use for the Testflinger server application | False |
| `model_uuid` | string | UUID of the Juju model to deploy into | True |
| `revision` | number | Revision of the charm to use | False |
| `units` | number | Number of units for the Testflinger server application | False |

Note that the initialization may timeout. That's fine as long as the setup actually completed. You can tell that the setup completed by checking if there are juju models created already:

```bash
multipass exec testflinger-juju -- juju models
```
### Outputs

## Initialize project's terraform
| Name | Type | Description |
| - | - | - |
| `application` | object | The deployed application object |
| `provides` | map(string) | Map of provides integration endpoints |
| `requires` | map(string) | Map of requires integration endpoints |

Now that everything has been set up, you can initialize the project's terraform.
## Usage
This module is intended to be used as part of a higher-level module.
When defining one, users should ensure that Terraform is aware of the `model_uuid`
dependency of the charm module.

In the terraform directory on your host machine, run:

```bash
multipass exec testflinger-juju -- terraform init
```

## Deploy everything

In the terraform directory on your host machine, run:

```bash
multipass exec testflinger-juju -- terraform apply -auto-approve
```
### Define a `data` source

Then wait for the deployment to settle and all the statuses to become active. You can watch the statuses via:
Define a `data.juju_model` source that looks up the target Juju model by name,
and pass the resulting UUID to the `model_uuid` input using `data.juju_model.<resource-name>.uuid`.
This ensures Terraform resolves the model data source before applying the module.
If the named model cannot be found, Terraform will fail during planning or apply
before creating any resources.

```bash
multipass exec testflinger-juju -- juju status --storage --relations --watch 5s
```hcl
data "juju_model" "testflinger_dev" {
name = "<model-name>"
}
```

## Connect to your deployment

Look at the IPv4 addresses of your testflinger-juju vm through:

```bash
multipass info testflinger-juju
```

One of these connect to the ingress enabled inside the VM. To figure out which one try the following command on each IP address until you get response:

```bash
curl --connect-to ::<ip-address> http://testflinger.local
```

Once you find the IP address add the following entry to your host machine's `/etc/hosts` file:

```text
<ip-address> testflinger.local
### Create module

Then call the module:

```hcl
module "testflinger" {
source = "git::https://github.com/canonical/testflinger.git//server/terraform?ref=<tag>"
model_uuid = data.juju_model.testflinger_dev.uuid
app_name = "<name>"
config = {
external_hostname = "testflinger.local"
http_proxy = ""
https_proxy = ""
no_proxy = "localhost,127.0.0.1,::1"
max_pool_size = "100"
jwt_signing_key = var.jwt_signing_key
testflinger_secrets_master_key = var.testflinger_secrets_master_key
}
}
```

After that you should be able to get to Testflinger frontend on your host machine's browser through the url `http://testflinger.local`. You should also be able to access the API through `http://testflinger.local/v1/`.

## Teardown

To take everything down you can start with terraform:

```bash
multipass exec testflinger-juju -- terraform destroy -auto-approve
```

The above step can take a while and may even get stuck with some applications in error state. You can watch it through:

```bash
multipass exec testflinger-juju -- juju status --storage --relations --watch 5s
```

To forcefully remove applications stuck in error state:

```bash
multipass exec testflinger-juju -- juju remove-application <application-name> --destroy-storage --force
```

Once everything is down and the juju model has been deleted you can stop the multipass VM:

```bash
multipass stop testflinger-juju
```

Optionally, delete the VM:

```bash
multipass delete --purge testflinger-juju
```
[juju-provider]: https://github.com/juju/terraform-provider-juju/
[juju-provider-docs]: https://registry.terraform.io/providers/juju/juju/latest/docs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.terraform.lock.hcl

.terraform/*

*.tfstate
Expand Down
Loading
Loading