Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dbbb40a9a8 | |||
| 7b3c156c7a | |||
|
b533e11611
|
|||
|
fabb609840
|
|||
|
36808ca32a
|
|||
|
56ea4c6178
|
|||
| 6c6eb8e161 | |||
| 5d09f36744 | |||
| af6e73101f | |||
| c12311ab9f | |||
| dfcbe54ebe | |||
| b2b2ad94b7 | |||
| 49c0913f2b | |||
| 0049839d98 | |||
| 59060033d3 | |||
| 8496c9de14 |
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
globs: "**/*.tf"
|
||||||
|
description: When a module depends on another module, it should only reference
|
||||||
|
the outputs of that module, not its internal resources or variables. This
|
||||||
|
promotes loose coupling and better maintainability.
|
||||||
|
alwaysApply: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Avoid tight coupling between modules by having one module depend on another's internal implementation details
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
|
# Terraform
|
||||||
.terraform/
|
.terraform/
|
||||||
*.tfstate
|
*.tfstate
|
||||||
*.tfstate.backup
|
*.tfstate.backup
|
||||||
.terraform.lock.hcl
|
.terraform.lock.hcl
|
||||||
|
|
||||||
|
# Local configs
|
||||||
terraform.tfvars
|
terraform.tfvars
|
||||||
*.override.tf
|
*.override.tf
|
||||||
|
|
||||||
|
.env
|
||||||
|
secrets.sh
|
||||||
@@ -1 +1,15 @@
|
|||||||
# Terraform Azure Bootcamp
|
# Aiimi Data CoP Azure Sandbox Environment
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 📂 Structure
|
||||||
|
- `modules/` → reusable Terraform modules (network, compute, database, etc.)
|
||||||
|
- `environments/` → environment-specific configs (`dev`, `prod`)
|
||||||
|
- `.github/workflows/terraform.yml` → CI/CD with GitHub Actions
|
||||||
|
|
||||||
|
## 🚀 Usage
|
||||||
|
```bash
|
||||||
|
cd environments/dev
|
||||||
|
terraform init
|
||||||
|
terraform plan
|
||||||
|
terraform apply
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
azurerm = {
|
||||||
|
source = "hashicorp/azurerm"
|
||||||
|
version = "4.52.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "azurerm" {
|
||||||
|
features {}
|
||||||
|
subscription_id = "0c8b6184-985d-4f31-b57e-c91f921241bd"
|
||||||
|
# JP Personal sub
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_resource_group" "rg" {
|
||||||
|
name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_account" "storage" {
|
||||||
|
name = var.storage_account_name
|
||||||
|
resource_group_name = azurerm_resource_group.rg.name
|
||||||
|
location = azurerm_resource_group.rg.location
|
||||||
|
account_tier = "Standard"
|
||||||
|
account_replication_type = "LRS"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_container" "terraform_state" {
|
||||||
|
name = "terraform-state"
|
||||||
|
storage_account_id = azurerm_storage_account.storage.id
|
||||||
|
}
|
||||||
|
|
||||||
|
data "http" "my_ip" {
|
||||||
|
url = "https://checkip.amazonaws.com/"
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = "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 = var.environment
|
||||||
|
project = var.project_name
|
||||||
|
}
|
||||||
|
|
||||||
|
module "sql_server" {
|
||||||
|
source = "../../modules/database"
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
environment = var.environment
|
||||||
|
sql_admin_password = var.sql_admin_password
|
||||||
|
sql_server_name = var.sql_server_name
|
||||||
|
olap_database_name = var.olap_database_name
|
||||||
|
oltp_database_name = var.oltp_database_name
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
sql_admin_password = var.sql_admin_password
|
||||||
|
sql_server_name = var.sql_server_name
|
||||||
|
olap_database_name = var.olap_database_name
|
||||||
|
oltp_database_name = var.oltp_database_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)
|
||||||
|
# }
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "sql_admin_password" {
|
||||||
|
description = "SQL Server administrator password"
|
||||||
|
type = string
|
||||||
|
default = "4-v3ry-53cr37-p455w0rd" # terraform docs
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "sql_server_name" {
|
||||||
|
default = "aiimi-cop-sandbox-sql-server"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "oltp_database_name" {
|
||||||
|
default = "oltp_master"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "olap_database_name" {
|
||||||
|
default = "olap_master"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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/"
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
variable "resource_group_name" {
|
||||||
|
default = "the_data_sandbox_prod"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "location" {
|
||||||
|
default = "uksouth"
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
resource "azurerm_network_interface" "nic" {
|
||||||
|
name = "vnic"
|
||||||
|
location = var.location
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
|
||||||
|
ip_configuration {
|
||||||
|
name = "internal"
|
||||||
|
subnet_id = var.subnet_id
|
||||||
|
private_ip_address_allocation = "Dynamic"
|
||||||
|
public_ip_address_id = azurerm_public_ip.vm_public.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_network_interface_security_group_association" "example" {
|
||||||
|
network_interface_id = azurerm_network_interface.nic.id
|
||||||
|
network_security_group_id = azurerm_network_security_group.vm_nsg.id
|
||||||
|
|
||||||
|
depends_on = [azurerm_network_security_group.vm_nsg]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_network_security_group" "vm_nsg" {
|
||||||
|
name = "vm-nsg"
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
|
||||||
|
security_rule {
|
||||||
|
name = "SSH"
|
||||||
|
priority = 1001
|
||||||
|
direction = "Inbound"
|
||||||
|
access = "Allow"
|
||||||
|
protocol = "Tcp"
|
||||||
|
source_port_range = "*"
|
||||||
|
destination_port_range = "22"
|
||||||
|
source_address_prefix = var.ex_ip
|
||||||
|
destination_address_prefix = "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_public_ip" "vm_public" {
|
||||||
|
name = "example-pip"
|
||||||
|
location = var.location
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
allocation_method = "Static"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_linux_virtual_machine" "vm" {
|
||||||
|
name = "example-vm"
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
size = var.vm_size
|
||||||
|
admin_username = var.admin_username
|
||||||
|
network_interface_ids = [azurerm_network_interface.nic.id]
|
||||||
|
admin_ssh_key {
|
||||||
|
username = var.admin_username
|
||||||
|
public_key = var.ssh_public_key
|
||||||
|
}
|
||||||
|
os_disk {
|
||||||
|
caching = "ReadWrite"
|
||||||
|
storage_account_type = "Standard_LRS"
|
||||||
|
}
|
||||||
|
source_image_reference {
|
||||||
|
offer = "ubuntu-24_04-lts"
|
||||||
|
publisher = "Canonical"
|
||||||
|
sku = "server"
|
||||||
|
version = "latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
volatile = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
output "vm_public_ip" {
|
||||||
|
value = azurerm_public_ip.vm_public
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
variable "resource_group_name" { type = string }
|
||||||
|
variable "location" { type = string }
|
||||||
|
variable "subnet_id" { type = string }
|
||||||
|
variable "vm_size" { type = string }
|
||||||
|
variable "admin_username" { type = string }
|
||||||
|
variable "ssh_public_key" { type = string }
|
||||||
|
variable "ex_ip" { type = string }
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
resource "azurerm_data_factory" "factory" {
|
||||||
|
name = var.data_factory_name
|
||||||
|
location = var.location
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
volatile = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Linked services for SQL databases
|
||||||
|
resource "azurerm_data_factory_linked_service_azure_sql_database" "ls_oltp_database" {
|
||||||
|
name = "ls_oltp_database"
|
||||||
|
data_factory_id = azurerm_data_factory.factory.id
|
||||||
|
connection_string = "data source=${var.sql_server_name}.database.windows.net;initial catalog=${var.oltp_database_name};user id=4dm1n157r470r;Password=${var.sql_admin_password};integrated security=False;encrypt=True;connection timeout=30"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_data_factory_linked_service_azure_sql_database" "ls_olap_database" {
|
||||||
|
name = "ls_olap_database"
|
||||||
|
data_factory_id = azurerm_data_factory.factory.id
|
||||||
|
connection_string = "data source=${var.sql_server_name}.database.windows.net;initial catalog=${var.olap_database_name};user id=4dm1n157r470r;Password=${var.sql_admin_password};integrated security=False;encrypt=True;connection timeout=30"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# }
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "sql_admin_password" {
|
||||||
|
description = "SQL Server administrator password"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "sql_server_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "oltp_database_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "olap_database_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
resource "azurerm_mssql_server" "sql_server" {
|
||||||
|
name = var.sql_server_name
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
version = "12.0"
|
||||||
|
administrator_login = "4dm1n157r470r" # terraform docs
|
||||||
|
administrator_login_password = var.sql_admin_password
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_mssql_database" "oltp_database" {
|
||||||
|
name = var.oltp_database_name
|
||||||
|
server_id = azurerm_mssql_server.sql_server.id
|
||||||
|
collation = "SQL_Latin1_General_CP1_CI_AS"
|
||||||
|
license_type = "LicenseIncluded" # tbc, developer?
|
||||||
|
sku_name = "S0" # az sql db list-editions -l uksouth -o table
|
||||||
|
storage_account_type = "Local"
|
||||||
|
geo_backup_enabled = false
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
volatile = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
# prevent_destroy = true
|
||||||
|
prevent_destroy = false
|
||||||
|
# it should actually be true, so data is safe
|
||||||
|
# however our sandbox environment should be
|
||||||
|
# ripped out completely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_mssql_database" "olap_database" {
|
||||||
|
name = var.olap_database_name
|
||||||
|
server_id = azurerm_mssql_server.sql_server.id
|
||||||
|
collation = "SQL_Latin1_General_CP1_CI_AS"
|
||||||
|
license_type = "LicenseIncluded" # tbc, developer?
|
||||||
|
sku_name = "S0" # az sql db list-editions -l uksouth -o table
|
||||||
|
storage_account_type = "Local"
|
||||||
|
geo_backup_enabled = false
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
volatile = true
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
# prevent_destroy = true
|
||||||
|
prevent_destroy = false
|
||||||
|
# it should actually be true, so data is safe
|
||||||
|
# however our sandbox environment should be
|
||||||
|
# ripped out completely.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
output "sql_server_id" {
|
||||||
|
value = azurerm_mssql_server.sql_server.id
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
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 "sql_admin_password" {
|
||||||
|
description = "SQL Server administrator password"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "sql_server_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "oltp_database_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "olap_database_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
resource "azurerm_virtual_network" "main" {
|
||||||
|
name = var.vnet_name
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
location = var.location
|
||||||
|
address_space = var.address_space
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_subnet" "subnets" {
|
||||||
|
for_each = var.subnets
|
||||||
|
name = each.key
|
||||||
|
resource_group_name = var.resource_group_name
|
||||||
|
virtual_network_name = azurerm_virtual_network.main.name
|
||||||
|
address_prefixes = [each.value]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,7 @@
|
|||||||
output "vnet_id" { value = "<placeholder>" }
|
output "vnet_id" {
|
||||||
|
value = azurerm_virtual_network.main.id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "subnet_ids" {
|
||||||
|
value = { for s in azurerm_subnet.subnets : s.name => s.id }
|
||||||
|
}
|
||||||
@@ -1 +1,36 @@
|
|||||||
variable "resource_group_name" { type = string }
|
variable "vnet_name" {
|
||||||
|
description = "Name of the Virtual Network"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "resource_group_name" {
|
||||||
|
description = "Resource Group to create resources in"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "location" {
|
||||||
|
description = "Azure region"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "address_space" {
|
||||||
|
description = "CIDR blocks for the VNet"
|
||||||
|
type = list(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subnets" {
|
||||||
|
description = "Map of subnet names to CIDR blocks"
|
||||||
|
type = map(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "environment" {
|
||||||
|
description = "Environment tag (dev/prod)"
|
||||||
|
type = string
|
||||||
|
default = "dev"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "project" {
|
||||||
|
description = "Project tag"
|
||||||
|
type = string
|
||||||
|
default = "TerraformBootcamp"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user