From 36808ca32ab7591dd81eeafe29a7fe1345eb6f9c Mon Sep 17 00:00:00 2001 From: Jake Pullen Date: Sat, 8 Nov 2025 12:47:09 +0000 Subject: [PATCH] potential ci/cd process in the works --- .github/workflows/terraform.yml | 68 +++++++++++++++++++++++++++++ .github/workflows/terraform.yml.old | 31 ------------- environments/dev/backend.tf | 0 environments/dev/main.tf | 55 +++++++++++++---------- environments/dev/outputs.tf | 7 --- environments/dev/variables.tf | 25 +++++++++++ environments/prod/main.tf | 50 +++++++++++++++++++++ environments/prod/variables.tf | 7 +++ modules/data_factory/main.tf | 13 ++++++ modules/data_factory/variables.tf | 30 +++++++++++++ 10 files changed, 226 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/terraform.yml delete mode 100644 .github/workflows/terraform.yml.old delete mode 100644 environments/dev/backend.tf delete mode 100644 environments/dev/outputs.tf create mode 100644 environments/prod/main.tf create mode 100644 environments/prod/variables.tf create mode 100644 modules/data_factory/main.tf create mode 100644 modules/data_factory/variables.tf diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..6642018 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,68 @@ +name: Terraform CI/CD + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + terraform: + runs-on: ubuntu-latest + env: + ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} + ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} + ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} + ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + + - name: Terraform Init (Dev) + run: | + cd environments/dev + terraform init + continue-on-error: false + + - name: Terraform Plan (Dev) + run: | + cd environments/dev + terraform plan -out=dev.plan + continue-on-error: false + + - name: Terraform Apply (Dev) + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + run: | + cd environments/dev + terraform apply dev.plan + continue-on-error: false + + - name: Terraform Init (Prod) + run: | + cd environments/prod + terraform init + continue-on-error: false + + - name: Terraform Plan (Prod) + run: | + cd environments/prod + terraform plan -out=prod.plan + continue-on-error: false + + - name: Terraform Apply (Prod) + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + run: | + cd environments/prod + terraform apply prod.plan + continue-on-error: false + + - name: Terraform Validate + run: | + cd environments/dev + terraform validate + cd ../prod + terraform validate \ No newline at end of file diff --git a/.github/workflows/terraform.yml.old b/.github/workflows/terraform.yml.old deleted file mode 100644 index 43e3e3b..0000000 --- a/.github/workflows/terraform.yml.old +++ /dev/null @@ -1,31 +0,0 @@ -# name: Terraform - -# on: -# pull_request: -# branches: [ "main" ] -# push: -# branches: [ "main" ] - -# jobs: -# terraform: -# runs-on: ubuntu-latest - -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 - -# - name: Setup Terraform -# uses: hashicorp/setup-terraform@v2 - -# - name: Terraform Init -# run: terraform -chdir=environments/dev init - -# - name: Terraform Validate -# run: terraform -chdir=environments/dev validate - -# - name: Terraform Plan -# run: terraform -chdir=environments/dev plan - -# - name: Terraform Apply -# if: github.event_name == 'push' && github.ref == 'refs/heads/main' -# run: terraform -chdir=environments/dev apply -auto-approve \ No newline at end of file diff --git a/environments/dev/backend.tf b/environments/dev/backend.tf deleted file mode 100644 index e69de29..0000000 diff --git a/environments/dev/main.tf b/environments/dev/main.tf index aa74af6..e898f42 100644 --- a/environments/dev/main.tf +++ b/environments/dev/main.tf @@ -1,24 +1,25 @@ terraform { required_providers { azurerm = { - source = "hashicorp/azurerm" + source = "hashicorp/azurerm" version = "4.52.0" } } } provider "azurerm" { - features{} + features {} subscription_id = "0c8b6184-985d-4f31-b57e-c91f921241bd" + # JP Personal sub } resource "azurerm_resource_group" "rg" { - name = "terraform_demo" - location = "uksouth" + name = var.resource_group_name + location = var.location } resource "azurerm_storage_account" "storage" { - name = "demoterraformbuildjp" + name = var.storage_account_name resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" @@ -26,8 +27,8 @@ resource "azurerm_storage_account" "storage" { } resource "azurerm_storage_container" "terraform_state" { - name = "terraform-state" - storage_account_id = azurerm_storage_account.storage.id + name = "terraform-state" + storage_account_id = azurerm_storage_account.storage.id } data "http" "my_ip" { @@ -37,26 +38,36 @@ data "http" "my_ip" { locals { my_ip = chomp(data.http.my_ip.response_body) ssh_public_key = file("~/.ssh/id_rsa.pub") + storage_account_url = "https://${azurerm_storage_account.storage.name}.blob.core.windows.net" } module "network" { source = "../../modules/network" - vnet_name = "dev-vnet" - resource_group_name = "terraform_demo" - location = "UK South" + vnet_name = "vnet" + resource_group_name = var.resource_group_name + location = var.location address_space = ["10.0.0.0/16"] subnets = { public = "10.0.1.0/24", private = "10.0.2.0/24" } - environment = "dev" - project = "TerraformBootcamp" + environment = var.environment + project = var.project_name } -module "compute" { - source = "../../modules/compute" - resource_group_name = "terraform_demo" - location = "UK South" - subnet_id = module.network.subnet_ids["public"] - vm_size = "Standard_B1s" - admin_username = "demo" - ssh_public_key = local.ssh_public_key - ex_ip = local.my_ip -} \ No newline at end of file +module "data_factory" { + source = "../../modules/data_factory" + resource_group_name = var.resource_group_name + location = var.location + environment = var.environment + storage_account_url = local.storage_account_url + data_factory_name = var.data_factory_name +} + +# module "compute" { +# source = "../../modules/compute" +# resource_group_name = var.resource_group_name +# location = var.location +# subnet_id = module.network.subnet_ids["public"] +# vm_size = "Standard_B1s" +# admin_username = "demo" +# ssh_public_key = file("~/.ssh/id_rsa.pub") +# ex_ip = chomp(data.http.my_ip.response_body) +# } diff --git a/environments/dev/outputs.tf b/environments/dev/outputs.tf deleted file mode 100644 index ab6ae44..0000000 --- a/environments/dev/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "my_ip" { - value = local.my_ip -} - -output "vm_public_ip" { - value = module.compute.vm_public_ip.ip_address -} \ No newline at end of file diff --git a/environments/dev/variables.tf b/environments/dev/variables.tf index e69de29..6845c6a 100644 --- a/environments/dev/variables.tf +++ b/environments/dev/variables.tf @@ -0,0 +1,25 @@ +variable "resource_group_name" { + default = "the_data_sandbox_dev" +} + +variable "location" { + default = "uksouth" +} + +variable "storage_account_name" { + default = "devdatasandboxstore" +} + +variable "environment" { + default = "dev" +} + +variable "project_name" { + default = "TheDataSandBox" +} + +variable "data_factory_name" { + description = "The unique name of the data factory" + type = string + default = "data-sandbox-factory-dev" +} \ No newline at end of file diff --git a/environments/prod/main.tf b/environments/prod/main.tf new file mode 100644 index 0000000..19d19ad --- /dev/null +++ b/environments/prod/main.tf @@ -0,0 +1,50 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.52.0" + } + } +} + +provider "azurerm" { + features{} + subscription_id = "0c8b6184-985d-4f31-b57e-c91f921241bd" + # JP Personal sub +} + +# Remote state backend for prod environment +terraform { + backend "azurerm" { + resource_group_name = "the_data_sandbox" + storage_account_name = "datasandboxstore" + container_name = "terraform-state" + key = "prod.tfstate" + } +} + +module "network" { + source = "../../modules/network" + vnet_name = "prod-vnet" + resource_group_name = "the_data_sandbox_prod" + location = "uksouth" + address_space = ["10.1.0.0/16"] + subnets = { public = "10.1.1.0/24", private = "10.1.2.0/24" } + environment = "prod" + project = "TheDataSandBox" +} + +module "compute" { + source = "../../modules/compute" + resource_group_name = "the_data_sandbox_prod" + location = "uksouth" + subnet_id = module.network.subnet_ids["public"] + vm_size = "Standard_D2s_v3" + admin_username = "demo" + ssh_public_key = file("~/.ssh/id_rsa.pub") + ex_ip = chomp(data.http.my_ip.response_body) +} + +data "http" "my_ip" { + url = "https://checkip.amazonaws.com/" +} \ No newline at end of file diff --git a/environments/prod/variables.tf b/environments/prod/variables.tf new file mode 100644 index 0000000..9b72bee --- /dev/null +++ b/environments/prod/variables.tf @@ -0,0 +1,7 @@ +variable "resource_group_name" { + default = "the_data_sandbox_prod" +} + +variable "location" { + default = "uksouth" +} \ No newline at end of file diff --git a/modules/data_factory/main.tf b/modules/data_factory/main.tf new file mode 100644 index 0000000..a547098 --- /dev/null +++ b/modules/data_factory/main.tf @@ -0,0 +1,13 @@ +resource "azurerm_data_factory" "factory" { + name = var.data_factory_name + location = var.location + resource_group_name = var.resource_group_name +} + +# TODO: Set up linked services and datasets +# resource "azurerm_data_factory_linked_service_data_lake_storage_gen2" "ls_container_storage" { +# name = "ls_container_storage" +# data_factory_id = azurerm_data_factory.factory.id +# url = var.storage_account_url + +# } \ No newline at end of file diff --git a/modules/data_factory/variables.tf b/modules/data_factory/variables.tf new file mode 100644 index 0000000..af4e806 --- /dev/null +++ b/modules/data_factory/variables.tf @@ -0,0 +1,30 @@ +variable "resource_group_name" { + description = "Resource Group to create resources in" + type = string +} + +variable "location" { + description = "Azure region" + type = string +} + +variable "environment" { + description = "Environment tag (dev/prod)" + type = string +} + +variable "project" { + description = "Project tag" + type = string + default = "TerraformBootcamp" +} + +variable "storage_account_url" { + description = "URL of the storage account to link to data factory" + type = string +} + +variable "data_factory_name" { + description = "The unique name of the data factory" + type = string +} \ No newline at end of file