From b35a2ed61fffcd3786586e3f6472b14ac04322cb Mon Sep 17 00:00:00 2001 From: Ali Ghanbarzadeh Date: Sat, 22 Apr 2023 21:23:58 +0200 Subject: [PATCH] Add stuff --- .github/workflows/infra.yaml | 113 +++++++++++++++++++++++++++++++++++ terraform/main.tf | 79 ++++++++++++++++++++++++ terraform/outputs.tf | 4 ++ terraform/variables.tf | 32 ++++++++++ 4 files changed, 228 insertions(+) create mode 100644 .github/workflows/infra.yaml create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/variables.tf diff --git a/.github/workflows/infra.yaml b/.github/workflows/infra.yaml new file mode 100644 index 000000000..d32c89512 --- /dev/null +++ b/.github/workflows/infra.yaml @@ -0,0 +1,113 @@ +name: Terraform Workflow Demo + +on: + push: + branches: [ "main" ] + paths: + - 'terraform/**' + - '.github/workflows/infra.yaml' + pull_request: + branches: [ "main" ] + paths: + - 'terraform/**' + - '.github/workflows/infra.yaml' + +jobs: + terraform: + permissions: + contents: 'read' + id-token: 'write' + pull-requests: 'write' #Needed to comment on the PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - id: 'plannerAuth' + if: github.ref != 'refs/heads/main' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v1.0.0' + with: + workload_identity_provider: 'projects/871215665939/locations/global/workloadIdentityPools/github/providers/github' + service_account: 'tf-plan@github-actions-gcp.iam.gserviceaccount.com' + + - id: 'applierAuth' + if: github.ref == 'refs/heads/main' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v1.0.0' + with: + workload_identity_provider: 'projects/871215665939/locations/global/workloadIdentityPools/github/providers/github' + service_account: 'tf-apply@github-actions-gcp.iam.gserviceaccount.com' + + - uses: hashicorp/setup-terraform@v2 + with: + terraform_version: 1.4.5 + + - id: fmt + name: Terraform fmt + working-directory: terraform + run: terraform fmt -check + + - id: init + name: Terraform Init + working-directory: terraform + run: terraform init -input=false -backend-config="prefix=terraform-demo" -backend-config="bucket=tf_state_prod_bucket" + + - id: validate + name: Terraform Validate + run: terraform validate -no-color + + - id: plan + name: Terraform Plan + working-directory: terraform + run: terraform plan -no-color + continue-on-error: true + + - uses: actions/github-script@v6 + if: github.event_name == 'pull_request' + env: + PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\` + #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` + #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` + #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` + +
Show Plan + + \`\`\`\n + ${process.env.PLAN} + \`\`\` + +
+ + *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + - name: Terraform Plan Status + if: steps.plan.outcome == 'failure' + run: exit 1 + + - name: Terraform Apply + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + working-directory: terraform + run: terraform apply -auto-approve -input=false + + - id: 'get-credentials' + uses: 'google-github-actions/get-gke-credentials@v1' + with: + cluster_name: 'gke0-test' + location: 'europe-west1' + + - id: 'get-pods' + run: 'kubectl get pods' + + - run: 'helm repo add nginx-stable https://helm.nginx.com/stable' + - run: 'helm repo update' + - run: 'helm install nginx-ingress --create-namespace --namespace nginx-ingress nginx-stable/nginx-ingress' + diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 000000000..4e76612b9 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,79 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "4.62.0" + } + } + + backend "gcs" {} +} + +#TODO parameterize gcp project ID in terraform plan/apply in CI + +module "gke_auth" { + source = "terraform-google-modules/kubernetes-engine/google//modules/auth" + version = "25.0.0" + depends_on = [module.gke] + project_id = var.project_id + location = module.gke.location + cluster_name = module.gke.name +} + +resource "local_file" "kubeconfig" { + content = module.gke_auth.kubeconfig_raw + filename = "kubeconfig-${var.env_name}" +} + +module "gcp-network" { + source = "terraform-google-modules/network/google" + version = "7.0.0" + project_id = var.project_id + network_name = "${var.network}-${var.env_name}" + + subnets = [ + { + subnet_name = "${var.subnetwork}-${var.env_name}" + subnet_ip = "10.10.0.0/16" + subnet_region = var.region + }, + ] + + secondary_ranges = { + "${var.subnetwork}-${var.env_name}" = [ + { + range_name = var.ip_range_pods_name + ip_cidr_range = "10.20.0.0/16" + }, + { + range_name = var.ip_range_services_name + ip_cidr_range = "10.30.0.0/16" + }, + ] + } +} + + +module "gke" { + source = "terraform-google-modules/kubernetes-engine/google//modules/private-cluster" + version = "25.0.0" + project_id = var.project_id + name = "${var.cluster_name}-${var.env_name}" + regional = true + region = var.region + network = module.gcp-network.network_name + subnetwork = module.gcp-network.subnets_names[0] + ip_range_pods = var.ip_range_pods_name + ip_range_services = var.ip_range_services_name + + node_pools = [ + { + name = "node-pool" + machine_type = "e2-medium" + node_locations = "europe-west1-b,europe-west1-c,europe-west1-d" + min_count = 1 + max_count = 2 + disk_size_gb = 30 + }, + ] +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 000000000..daa8a4f97 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,4 @@ +output "cluster_name" { + description = "Cluster name" + value = module.gke.name +} diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 000000000..e0f002cba --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,32 @@ +variable "project_id" { + description = "The project ID to host the cluster in" + default = "github-actions-gcp" +} +variable "cluster_name" { + description = "The name for the GKE cluster" + default = "gke0" +} +variable "env_name" { + description = "The environment for the GKE cluster" + default = "test" +} +variable "region" { + description = "The region to host the cluster in" + default = "europe-west1" +} +variable "network" { + description = "The VPC network created to host the cluster in" + default = "gke-network" +} +variable "subnetwork" { + description = "The subnetwork created to host the cluster in" + default = "gke-subnet" +} +variable "ip_range_pods_name" { + description = "The secondary ip range to use for pods" + default = "ip-range-pods" +} +variable "ip_range_services_name" { + description = "The secondary ip range to use for services" + default = "ip-range-services" +}