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
34 changes: 34 additions & 0 deletions .github/workflows/terraform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Terraform

on:
pull_request:
branches:
- main
paths:
- '**/*.tf'

jobs:
lint-terraform:
name: Terraform lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo snap install terraform --classic
sudo snap install just --classic
- name: Lint the Terraform modules
run: just lint-terraform
validate-terraform:
name: Terraform validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo snap install terraform --classic
sudo snap install just --classic
- name: Validate the Terraform modules
run: just validate-terraform
23 changes: 23 additions & 0 deletions .github/workflows/workflows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: GH Workflows

on:
pull_request:
branches:
- main
paths:
- '.github/**/*.yml'
- '.github/**/*.yaml'

jobs:
lint-workflows:
name: Workflows Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo snap install astral-uv --classic
sudo snap install just --classic
- name: Lint the workflows
run: just lint-workflows
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,32 @@ docs/.DS_Store
docs/__pycache__
docs/.idea/
docs/.vscode/

# Terraform
**/.terraform/*
*.tfstate
*.tfstate.*
*.tfplan
*.backup
*.bak
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Ignore CLI configuration files
.terraformrc
terraform.rc
.terraform.lock.hcl
2 changes: 1 addition & 1 deletion docs/explanation/tls-encryption-in-cos.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## COS

When deploying COS using [the provided Terraform module](https://github.com/canonical/observability/tree/main/terraform/modules/cos), it will by default be deployed using a self-signed certificate authority. If you have other certificate requirements, you'll be able to replace the self-signed-certificates operator with another TLS operator of your liking, consulting the "Providing" section of [the `tls-certificates` interface page on Charmhub](https://charmhub.io/integrations/tls-certificates).
When deploying COS using [the provided Terraform module](https://github.com/canonical/observability-stack/tree/main/terraform/cos), it will by default be deployed using a self-signed certificate authority. If you have other certificate requirements, you'll be able to replace the self-signed-certificates operator with another TLS operator of your liking, consulting the "Providing" section of [the `tls-certificates` interface page on Charmhub](https://charmhub.io/integrations/tls-certificates).

## COS Lite

Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial/installation/cos-canonical-k8s-sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Create a `cos-canonical-k8s-sandbox.tf` file with the following Terraform module

```
module "cos" {
source = "git::https://github.com/canonical/observability//terraform/modules/cos"
source = "git::https://github.com/canonical/observability-stack//terraform/cos"
model_name = "cos"
channel = "1/stable"
s3_endpoint = "http://{{IPADDR}}:8080"
Expand All @@ -34,12 +34,12 @@ module "cos" {
}
```

<!-- warn users of the 2 Juju Provider bugs -->
<!-- add `enable_external_tls` when available -->
<!-- probably set the default track in the COS module to `1/stable`, then remove the key from the tutorial -->
<!-- change `s3_user` to `s3_access_key` (and `s3_password` to `s3_secret_key`) once it's changed in the module -->
<!-- if Field wants, allow setting `anti_affinity` by something other than `kubernetes/hostname` -->

**Note**: You can customize further the number of units of each distributed charm and other aspects of COS: have a look at the [`variables.tf`](https://github.com/canonical/observability/blob/main/terraform/modules/cos/variables.tf) file of the COS Terraform module for the complete documentation.
**Note**: You can customize further the number of units of each distributed charm and other aspects of COS: have a look at the [`variables.tf`](../../../terraform/cos/variables.tf) file of the COS Terraform module for the complete documentation.

<!-- Once we allow enabling internal TLS and external TLS separately, add the explanation to this tutorial -->

Expand Down
22 changes: 11 additions & 11 deletions docs/tutorial/installation/cos-canonical-k8s-sandbox.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module "cos" {
source = "git::https://github.com/canonical/observability//terraform/modules/cos"
model_name = "cos"
channel = "1/stable"
s3_endpoint = "http://{{IPADDR}}:8080"
s3_password = "secret-key"
s3_user = "access-key"
loki_bucket = "loki"
mimir_bucket = "mimir"
tempo_bucket = "tempo"
ssc_channel = "1/stable"
anti_affinity = true
source = "git::https://github.com/canonical/observability-stack//terraform/cos"
model = "cos-2"
channel = "1/stable"
s3_endpoint = "http://192.168.88.12:8080"
s3_secret_key = "secret-key"
s3_access_key = "access-key"
loki_bucket = "loki"
mimir_bucket = "mimir"
tempo_bucket = "tempo"
ssc_channel = "1/stable"
anti_affinity = true
}
42 changes: 42 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
set quiet # Recipes are silent by default
set export # Just variables are exported to the environment

terraform := `which terraform || which tofu || echo ""` # require 'terraform' or 'opentofu'

[private]
default:
just --list

# Lint everything
[group("Lint")]
lint: lint-workflows lint-terraform

# Format everything
[group("Format")]
fmt: format-terraform

# Lint the Github workflows
[group("Lint")]
lint-workflows:
uvx --from=actionlint-py actionlint

# Lint the Terraform modules
[group("Lint")]
[working-directory("./terraform")]
lint-terraform:
if [ -z "${terraform}" ]; then echo "ERROR: please install terraform or opentofu"; exit 1; fi
set -e; for repo in */; do (cd "$repo" && echo "Processing ${repo%/}..." && $terraform init -upgrade -reconfigure && $terraform fmt -check -recursive -diff) || exit 1; done
Comment thread
MichaelThamm marked this conversation as resolved.

# Format the Terraform modules
[group("Format")]
[working-directory("./terraform")]
format-terraform:
if [ -z "${terraform}" ]; then echo "ERROR: please install terraform or opentofu"; exit 1; fi
set -e; for repo in */; do (cd "$repo" && echo "Processing ${repo%/}..." && $terraform init -upgrade -reconfigure && $terraform fmt -recursive -diff) || exit 1; done

# Validate the Terraform modules
[group("Validate")]
[working-directory("./terraform")]
validate-terraform:
if [ -z "${terraform}" ]; then echo "ERROR: please install terraform or opentofu"; exit 1; fi
set -e; for repo in */; do (cd "$repo" && echo "Processing ${repo%/}..." && $terraform init -upgrade -reconfigure && $terraform validate) || exit 1; done
3 changes: 3 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Dev workflow

Use the [justfile](https://github.com/canonical/observability-stack/blob/main/justfile) to lint, format, and validate your TF changes.
131 changes: 131 additions & 0 deletions terraform/aws-infra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# From Zero to COS: AWS Provisioning & Deployment

This directory contains Terraform modules for automating the process of bootstrapping a fresh AWS account to a fully running instance of COS deployed on a 3-node EKS cluster.


## Prerequisites

Make sure you have the following installed:

- [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) >= v1.10.4
- [AWS CLI](https://github.com/aws/aws-cli) >= 2.26.7
- [Juju](https://snapcraft.io/juju) >= 3.0.3
- [Just](https://github.com/casey/just) >= 1.40.0

### AWS Credentials Setup

Before running any commands, ensure your AWS credentials are configured on the host:

You can do this using one of the following methods:

- [Environment variables](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-envvars.html)
- [Credentials file](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html)

---


## Usage

### Bootstrap AWS infrastructure + Juju controller:
In order to provision the AWS infrastructure required for COS, create a `main.tf` file with the following content.

```hcl
module "aws_infra" {
source = "git::https://github.com/canonical/observability-stack//terraform/aws-infra"
region = var.region
cos_cloud_name = var.cos_cloud_name
cos_controller_name = var.cos_controller_name
cos_model_name = var.cos_model_name
}

variable "region" {
description = "The AWS region where the resources will be provisioned."
type = string
}

variable "cos_cloud_name" {
description = "The name to assign to the Kubernetes cloud when running 'juju add-k8s'."
type = string
default = "cos-cloud"
}

variable "cos_controller_name" {
description = "The name to assign to the Juju controller that will manage COS."
type = string
default = "cos-controller"
}

variable "cos_model_name" {
description = "The name of the Juju model where COS will be deployed."
type = string
default = "cos"
}

```
Then, create a `terraform.tfvars` file with the following content:

```hcl
region = "<aws-region>"
cos_cloud_name = "<cos-cloud-name>"
cos_controller_name = "<cos-controller-name>"
cos_model_name = "<cos-model-name>"
```
Then, use terraform to deploy the module:
```bash
terraform init
terraform apply -var-file=terraform.tfvars
```
### Full bootstrap: go from zero to COS:

You can fully bootstrap AWS infra and COS in one of two ways:
#### Option 1: Manual 2-Step Process
1. [Bootstrap AWS infra](#bootstrap-aws-infrastructure--juju-controller)

Set up the necessary infrastructure and Juju controller on AWS using the `aws-infra` module.

2. [Deploy COS on the freshly created infra](../cos/README.md#deploy-cos-on-aws-eks)

Use the output from step 1 to deploy COS on top of your provisioned infrastructure using the `cos` module.

#### Option 2: Automated via `just`

Clone this repository and run the appropriate `just` command to fully automate the bootstrap process.
This command handles:

1. Bootstrapping the AWS infrastructure
2. Piping all required input to deploy COS on top


Create a `terraform.tfvars` file with the following content:
```hcl
region = "<your-aws-region>"
# Add other optional variables below
cos_cloud_name = "<cos_cloud_name>"
cos_controller_name = "<cos_controller_name>"
cos_model_name = "<cos_model_name>"
```
Then, run `just apply`

---


## Inputs

| Variable Name | Description |
|----------|-------------------------|
| region | AWS region to provision resources in |
| cos_cloud_name | The name to assign to the Kubernetes cloud when running 'juju add-k8s' |
| cos_controller_name | The name to assign to the Juju controller that will manage COS |
| cos_model_name | The name of the Juju model where COS will be deployed |

---

## Available Commands (via `just`)

- `just init` – Initialize Terraform for AWS infra and COS
- `just apply` – Provision AWS infrastructure, then pipe the necessary outputs to provision COS on top
- `just destroy` – Tear down everything (COS + infra)

---


39 changes: 39 additions & 0 deletions terraform/aws-infra/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
set quiet # Recipes are silent by default

init:
terraform init
terraform -chdir=../cos init

apply: init apply_infra apply_cos

destroy: destroy_cos destroy_infra

apply_infra:
terraform apply

apply_cos:
terraform -chdir=../cos apply \
-var="loki_bucket=$(terraform output -raw loki_bucket)" \
-var="tempo_bucket=$(terraform output -raw tempo_bucket)" \
-var="mimir_bucket=$(terraform output -raw mimir_bucket)" \
-var="s3_endpoint=$(terraform output -raw s3_endpoint)" \
-var="s3_access_key=$(terraform output -raw s3_access_key)" \
-var="s3_secret_key=$(terraform output -raw s3_secret_key)" \
-var="model=$(terraform output -raw cos_model)" \
-var="ssc_channel=1/edge" \
-var="cloud=aws" \

destroy_infra:
terraform destroy

destroy_cos:
terraform -chdir=../cos destroy \
-var="loki_bucket=$(terraform output -raw loki_bucket)" \
-var="tempo_bucket=$(terraform output -raw tempo_bucket)" \
-var="mimir_bucket=$(terraform output -raw mimir_bucket)" \
-var="s3_endpoint=$(terraform output -raw s3_endpoint)" \
-var="s3_access_key=$(terraform output -raw s3_access_key)" \
-var="s3_secret_key=$(terraform output -raw s3_secret_key)" \
-var="model=$(terraform output -raw cos_model)" \
-var="ssc_channel=1/edge" \
-var="cloud=aws" \
Loading
Loading