name: Terraform Apply CI on: push: branches: - main paths: - 'terraform/**' - '.forgejo/workflows/terraform-apply.yml' permissions: contents: read jobs: terraform: runs-on: docker steps: - name: Checkout uses: actions/checkout@v4 - name: Install Dependencies run: | # Install tools: wget (download terraform), unzip (extract), curl (optional) # Runner uses node:22-bookworm (Debian), not Alpine, so use apt-get apt-get update && apt-get install -y wget unzip curl - name: Setup Terraform run: | TF_VERSION=1.8.4 TF_URL="https://releases.hashicorp.com/terraform/${TF_VERSION}/terraform_${TF_VERSION}_linux_amd64.zip" mkdir -p /tmp/tf-bin cd /tmp/tf-bin wget -q "$TF_URL" || { echo "Failed to download terraform"; exit 1; } unzip -q "terraform_${TF_VERSION}_linux_amd64.zip" chmod +x terraform ./terraform version echo "/tmp/tf-bin" >> $GITHUB_PATH - name: Terraform Format Check run: terraform fmt -check -recursive terraform/ continue-on-error: true - name: Generate In-Cluster Kubeconfig run: | mkdir -p /tmp cat > /tmp/kubeconfig << 'EOF' apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt server: https://kubernetes.default:443 name: in-cluster contexts: - context: cluster: in-cluster user: terraform name: in-cluster current-context: in-cluster users: - name: terraform user: tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token EOF chmod 600 /tmp/kubeconfig - name: Configure AWS Credentials env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | mkdir -p ~/.aws cat > ~/.aws/credentials << EOF [minio] aws_access_key_id = $AWS_ACCESS_KEY_ID aws_secret_access_key = $AWS_SECRET_ACCESS_KEY EOF chmod 600 ~/.aws/credentials - name: Terraform Init working-directory: terraform env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_VAR_kubeconfig_path: /tmp/kubeconfig TF_SKIP_CREDENTIALS_VALIDATION: "true" TF_SKIP_REGION_VALIDATION: "true" TF_SKIP_REQUESTING_ACCOUNT_ID: "true" run: | terraform init \ -backend-config="bucket=terraform-state" \ -backend-config="key=homelab/terraform.tfstate" \ -backend-config="region=us-east-1" \ -backend-config="endpoint=http://minio.storage.svc.cluster.local:9000" \ -backend-config="access_key=$AWS_ACCESS_KEY_ID" \ -backend-config="secret_key=$AWS_SECRET_ACCESS_KEY" \ -backend-config="skip_credentials_validation=true" \ -backend-config="use_path_style=true" - name: Pull Terraform State working-directory: terraform env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_SKIP_CREDENTIALS_VALIDATION: "true" run: | echo "Verifying state is accessible from MinIO..." terraform state pull > /tmp/tfstate-verify.json STATE_SIZE=$(wc -c < /tmp/tfstate-verify.json) RESOURCE_COUNT=$(terraform state list | wc -l) echo "State size: $STATE_SIZE bytes" echo "Resources in state: $RESOURCE_COUNT" - name: Terraform Validate working-directory: terraform run: terraform validate - name: Terraform Plan working-directory: terraform env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_VAR_kubeconfig_path: /tmp/kubeconfig TF_SKIP_CREDENTIALS_VALIDATION: "true" run: | terraform plan -out=tfplan - name: Terraform Apply working-directory: terraform env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_VAR_kubeconfig_path: /tmp/kubeconfig TF_SKIP_CREDENTIALS_VALIDATION: "true" run: | terraform apply -auto-approve tfplan