diff --git a/.github/workflows/tofu.yaml b/.github/workflows/tofu.yaml new file mode 100644 index 0000000..600c3fc --- /dev/null +++ b/.github/workflows/tofu.yaml @@ -0,0 +1,47 @@ +name: OpenTofu + +on: + push: + branches: + - main + paths: + - 'infrastructure/**' + +defaults: + run: + working-directory: infrastructure/equinix-metal + +jobs: + tofu: + name: OpenTofu + runs-on: ubuntu-latest + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + TF_VAR_equinix_auth_token: ${{ secrets.EQUINIX_AUTH_TOKEN }} + TF_VAR_equinix_project_id: ${{ secrets.EQUINIX_PROJECT_ID }} + TF_VAR_flux_github_token: ${{ secrets.FLUX_GITHUB_TOKEN }} + TF_VAR_k3s_token: ${{ secrets.K3S_TOKEN }} + TF_VAR_ssh_public_key: ${{ secrets.SSH_PUBLIC_KEY }} + steps: + - uses: actions/checkout@v3 + - uses: opentofu/setup-opentofu@v1 + + - name: Add SSH key + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-agent -a $SSH_AUTH_SOCK > /dev/null + ssh-add ~/.ssh/id_rsa + env: + SSH_AUTH_SOCK: /tmp/ssh_agent.sock + + - name: tofu init + run: tofu init + + - name: tofu plan + run: tofu plan + + - name: tofu apply + run: tofu apply -auto-approve diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3fd45cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +infrastructure/equinix-metal/.terraform/ +infrastructure/equinix-metal/terraform.tfvars diff --git a/infrastructure/equinix-metal/main.tf b/infrastructure/equinix-metal/main.tf new file mode 100644 index 0000000..6960000 --- /dev/null +++ b/infrastructure/equinix-metal/main.tf @@ -0,0 +1,155 @@ +terraform { + required_providers { + equinix = { + source = "equinix/equinix" + version = "1.22.0" + } + null = { + source = "hashicorp/null" + version = "3.2.2" + } + } + + backend "s3" { + bucket = "green-reviews-state-bucket" + key = "opentofu/terraform.tfstate" + region = "eu-central-1" + encrypt = true + } +} + +provider "equinix" { + auth_token = var.equinix_auth_token +} + +resource "equinix_metal_project_ssh_key" "ssh_key" { + name = var.cluster_name + project_id = var.equinix_project_id + public_key = var.ssh_public_key +} + +resource "equinix_metal_device" "control_plane" { + hostname = "${var.cluster_name}-control-plane" + plan = var.device_plan + metro = var.device_metro + operating_system = var.device_os + billing_cycle = var.billing_cycle + project_id = var.equinix_project_id + depends_on = [equinix_metal_project_ssh_key.ssh_key] + project_ssh_key_ids = [equinix_metal_project_ssh_key.ssh_key.id] + + behavior { + allow_changes = [ + "custom_data", + "user_data" + ] + } + + connection { + user = "root" + private_key = file(var.ssh_private_key_path) + host = self.access_public_ipv4 + } + + provisioner "remote-exec" { + inline = [ + "curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${var.k3s_version} K3S_TOKEN=${var.k3s_token} sh -s - server --node-taint node-role.kubernetes.io/control-plane=:NoSchedule --flannel-backend=none --disable-network-policy --disable=traefik", + "systemctl is-active --quiet k3s.service", + ] + } +} + +resource "equinix_metal_device" "worker" { + for_each = toset(var.worker_nodes) + hostname = "${var.cluster_name}-${each.value}" + plan = var.device_plan + metro = var.device_metro + operating_system = var.device_os + billing_cycle = var.billing_cycle + project_id = var.equinix_project_id + project_ssh_key_ids = [equinix_metal_project_ssh_key.ssh_key.id] + depends_on = [equinix_metal_device.control_plane] + user_data = <