diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..b573310 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,114 @@ +# Populates terraform/prod.tfvars at job runtime from GitHub Secrets / Variables, +# then runs Terraform (plan on PR/push; apply only when you run the workflow manually). +# +# Configure in the repo: +# Settings → Secrets and variables → Actions +# +# Secrets (required for plan/apply): +# TF_NETCUP_CCP_API_KEY +# TF_NETCUP_CCP_API_PASSWORD +# TF_CLOUDFLARE_API_TOKEN +# +# Variables (optional; sensible defaults are applied in the "Write prod.tfvars" step): +# TF_DNS_DOMAIN +# TF_SUBDOMAIN_NAME +# TF_PAGES_PROJECT_NAME +# TF_PAGES_CNAME_TARGET (leave unset for ".pages.dev") +# TF_NETCUP_CUSTOMER_NUMBER +# TF_CLOUDFLARE_ACCOUNT_ID + +name: Terraform + +on: + pull_request: + paths: + - "terraform/**" + - ".github/workflows/terraform.yml" + push: + branches: + - main + paths: + - "terraform/**" + - ".github/workflows/terraform.yml" + workflow_dispatch: + +concurrency: + group: terraform-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +defaults: + run: + working-directory: terraform + +jobs: + terraform: + runs-on: ubuntu-latest + # Fork PRs do not receive repository secrets; skip to avoid failing on missing credentials. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: "1.7.5" + terraform_wrapper: false + + - name: Write prod.tfvars + env: + DNS_DOMAIN: ${{ vars.TF_DNS_DOMAIN }} + SUBDOMAIN_NAME: ${{ vars.TF_SUBDOMAIN_NAME }} + PAGES_PROJECT_NAME: ${{ vars.TF_PAGES_PROJECT_NAME }} + PAGES_CNAME_TARGET: ${{ vars.TF_PAGES_CNAME_TARGET }} + NETCUP_CUSTOMER_NUMBER: ${{ vars.TF_NETCUP_CUSTOMER_NUMBER }} + CLOUDFLARE_ACCOUNT_ID: ${{ vars.TF_CLOUDFLARE_ACCOUNT_ID }} + NETCUP_CCP_API_KEY: ${{ secrets.TF_NETCUP_CCP_API_KEY }} + NETCUP_CCP_API_PASSWORD: ${{ secrets.TF_NETCUP_CCP_API_PASSWORD }} + CLOUDFLARE_API_TOKEN: ${{ secrets.TF_CLOUDFLARE_API_TOKEN }} + run: | + set -euo pipefail + : "${NETCUP_CCP_API_KEY:?Set secret TF_NETCUP_CCP_API_KEY}" + : "${NETCUP_CCP_API_PASSWORD:?Set secret TF_NETCUP_CCP_API_PASSWORD}" + : "${CLOUDFLARE_API_TOKEN:?Set secret TF_CLOUDFLARE_API_TOKEN}" + : "${NETCUP_CUSTOMER_NUMBER:?Set variable TF_NETCUP_CUSTOMER_NUMBER}" + : "${CLOUDFLARE_ACCOUNT_ID:?Set variable TF_CLOUDFLARE_ACCOUNT_ID}" + : "${PAGES_PROJECT_NAME:?Set variable TF_PAGES_PROJECT_NAME}" + + dns_domain="${DNS_DOMAIN:-webdev-webdesign.com}" + subdomain_name="${SUBDOMAIN_NAME:-webring}" + pages_cname_target="${PAGES_CNAME_TARGET:-}" + + umask 077 + cat > prod.tfvars <.pages.dev") +# pages_cname_target = "your-pages-project-name.pages.dev" + +netcup_customer_number = "123456" +cloudflare_account_id = "paste-account-id-from-dashboard" + +# Secrets — locally: export TF_VAR_netcup_ccp_api_key / … or put them in a gitignored tfvars file. +# +# CI (GitHub Actions): do not commit prod.tfvars. The workflow .github/workflows/terraform.yml +# writes terraform/prod.tfvars from repository Secrets / Variables (see comments in that file). diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..8538791 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,56 @@ +# All input variables for this module (Netcup + Cloudflare Pages). + +# --- Netcup (DNS at Netcup CCP) --- + +variable "netcup_customer_number" { + description = "Netcup customer number (same as CCP login)." + type = string +} + +variable "netcup_ccp_api_key" { + description = "Netcup CCP API key (CCP → Stammdaten → API)." + type = string + sensitive = true +} + +variable "netcup_ccp_api_password" { + description = "Netcup CCP API password." + type = string + sensitive = true +} + +variable "dns_domain" { + description = "Apex domain whose DNS zone Netcup hosts (e.g. webdev-webdesign.com)." + type = string + default = "webdev-webdesign.com" +} + +variable "subdomain_name" { + description = "Hostname label managed in Netcup (webring → webring.webdev-webdesign.com)." + type = string + default = "webring" +} + +# --- Cloudflare Pages (hostname on the project) --- + +variable "cloudflare_api_token" { + description = "API token with Account → Cloudflare Pages → Edit (and Pages Read). Not used for Netcup DNS." + type = string + sensitive = true +} + +variable "cloudflare_account_id" { + description = "Cloudflare account ID (Workers & Pages overview, or URL in dashboard)." + type = string +} + +variable "pages_project_name" { + description = "Pages project name as shown in the Cloudflare dashboard (slug)." + type = string +} + +variable "pages_cname_target" { + description = "CNAME target in Netcup. Leave empty to use \".pages.dev\"." + type = string + default = "" +} \ No newline at end of file