Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ terraform.rc

misc/experimental
.DS_Store
.idea
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ repos:
exclude: |
(?x)^(
config/README.md|
cluster/README.md
cluster/README.md|
azure/README.md
)$
- id: mixed-line-ending
- id: check-yaml
Expand Down
62 changes: 62 additions & 0 deletions azure/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 93 additions & 0 deletions azure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Azure Terraform Functionality

This project uses Terraform to automate the deployment of Azure resources, including resource groups, virtual networks, subnets, Azure Kubernetes Service (ASK), Azure Container Registry (ACR), and PostgreSQL Flexible Server.

## Directory Structure

```
azure/
├── main.tf # Main configuration file, defining resource groups and module references
├── provider.tf # Provider configuration (azurerm, kubernetes, local)
├── variables.tf # Global variable definitions
├── outputs.tf # Global output definitions
├── network/ # Network module
│ ├── main.tf # Virtual network and subnet configuration
│ ├── variables.tf # Network module variable definitions
│ └── outputs.tf # Network module output definitions
├── kubernetes/ # Kubernetes module
│ ├── main.tf # ASK cluster configuration
│ ├── rbac.tf # Role assignment from ASK to ACR
│ ├── variables.tf # Kubernetes module variable definitions
│ └── outputs.tf # Kubernetes module output definitions
├── registry/ # Container registry module
│ ├── main.tf # ACR configuration
│ ├── variables.tf # Container registry module variable definitions
│ └── outputs.tf # Container registry module output definitions
└── postgresql-flexible-server/ # PostgreSQL Flexible Server module
├── main.tf # PostgreSQL server configuration
├── variables.tf # PostgreSQL module variable definitions
└── outputs.tf # PostgreSQL module output definitions
```

## Functionality

- **Resource Group**: Creates an Azure resource group to organize all resources.
- **Virtual Network**: Creates a VNet and subnet to provide a network environment for ASK.
- **ASK Cluster**: Deploys Azure Kubernetes Service, configuring default node pools, network policies, and key vault integration.
- **ACR**: Creates an Azure Container Registry for storing and managing container images.
- **Role Assignment**: Assigns the AcrPull role to ASK for ACR, enabling integration between ASK and ACR.
- **PostgreSQL Flexible Server**: Deploys a PostgreSQL 16 server with the following features:
- Private DNS Zone integration
- VNet integration
- Automatic backup enabled
- High availability configuration
- Zone redundancy disabled (zone = null)

## Usage

1. **Initialize**: Run the following command in the `azure` directory to initialize the Terraform working directory:
```bash
terraform init
```

2. **Plan**: Run the following command to view the resource creation plan:
```bash
terraform plan
```

3. **Apply**: Run the following command to create the resources:
```bash
terraform apply
```

## Dependencies

- Terraform version >= 1.5.7
- Azure Provider (hashicorp/azurerm) >= 4.28.0
- Kubernetes Provider (hashicorp/kubernetes) >= 2.36.0
- Local Provider (hashicorp/local) >= 2.0.0

## Notes

- This project only manages Azure resources and does not involve local Kubernetes operations.
- If you need to manage Kubernetes resources, generate a kubeconfig via CI/CD or remotely and pass it to the provider.
- All sensitive information (such as ACR passwords, kube_config, and PostgreSQL credentials) is marked as sensitive and will not be displayed in plain text in the output.
- The PostgreSQL server is configured with private networking, so access is only available from within the VNet or through a VPN/Private Link.

## Outputs

- `resource_group_name`: Name of the resource group
- `virtual_network_name`: Name of the virtual network
- `virtual_network_id`: ID of the virtual network
- `subnet_id`: ID of the subnet
- `kubernetes_cluster_name`: Name of the Kubernetes cluster
- `kubernetes_cluster_id`: ID of the Kubernetes cluster
- `kube_config`: Kubernetes configuration (sensitive)
- `container_registry_name`: Name of the container registry
- `container_registry_login_server`: Login server of the container registry
- `container_registry_admin_username`: Admin username of the container registry
- `container_registry_admin_password`: Admin password of the container registry (sensitive)
- `postgresql_fqdn`: The fully qualified domain name of the PostgreSQL server
- `postgresql_instance_id`: The instance ID of the PostgreSQL server
- `postgresql_password`: The administrator password (sensitive)
- `postgresql_username`: The administrator username
23 changes: 23 additions & 0 deletions azure/kubernetes/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions azure/kubernetes/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
terraform {
required_version = ">= 1.0.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.0.0"
}
}
}

# Azure kubernetes Cluster
resource "azurerm_kubernetes_cluster" "main" {
name = "${var.project}-${var.environment}-Kubernetes"
location = var.location
resource_group_name = var.resource_group_name
dns_prefix = "${var.project}-${var.environment}"
kubernetes_version = var.kubernetes_version
node_resource_group = "${var.project}-${var.environment}-Kubernetes-resources"

default_node_pool {
name = "default"
vm_size = var.kubernetes_vm_size
vnet_subnet_id = var.subnet_id
node_count = var.node_count
}

identity {
type = "SystemAssigned"
}

network_profile {
network_plugin = "azure"
network_policy = "azure"
network_mode = "transparent"
network_plugin_mode = "overlay"
load_balancer_sku = "standard"
service_cidr = var.service_cidr
dns_service_ip = var.dns_service_ip
pod_cidr = var.pod_cidr
}

# Enable RBAC
role_based_access_control_enabled = true

# Enable OMS Agent logging
oms_agent {
log_analytics_workspace_id = var.log_analytics_workspace_id
}

# Restrict API server access to specific IP ranges
api_server_access_profile {
authorized_ip_ranges = var.authorized_ip_ranges
}

key_vault_secrets_provider {
secret_rotation_enabled = true
}

tags = var.tags

#checkov:skip=CKV_AZURE_115,CKV_AZURE_116,CKV_AZURE_117,CKV_AZURE_226,CKV_AZURE_232,CKV_AZURE_141,CKV_AZURE_168,CKV_AZURE_170,CKV_AZURE_171,CKV_AZURE_227: This is implicitly guranateed and public access is blocked for Azure Kubernetes Service

}
15 changes: 15 additions & 0 deletions azure/kubernetes/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "cluster_id" {
description = "Kubernetes cluster ID"
value = azurerm_kubernetes_cluster.main.id
}

output "kubelet_identity" {
description = "Kubelet identity"
value = azurerm_kubernetes_cluster.main.kubelet_identity
}

output "kube_config" {
description = "Kubernetes config"
value = azurerm_kubernetes_cluster.main.kube_config_raw
sensitive = true
}
6 changes: 6 additions & 0 deletions azure/kubernetes/rbac.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "azurerm_role_assignment" "ask_to_acr" {
principal_id = azurerm_kubernetes_cluster.main.kubelet_identity[0].object_id
role_definition_name = "AcrPull"
scope = var.acr_id
skip_service_principal_aad_check = true
}
86 changes: 86 additions & 0 deletions azure/kubernetes/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
variable "project" {
description = "Project name"
type = string
}

variable "environment" {
description = "Environment name"
type = string
}

variable "location" {
description = "Azure region"
type = string
}

variable "resource_group_name" {
description = "Resource group name"
type = string
}

variable "kubernetes_version" {
description = "Kubernetes version"
type = string
default = "1.31.7"
}

variable "kubernetes_vm_size" {
description = "VM size for Azure kubernetes nodes"
type = string
default = "Standard_D2s_v3"
}

variable "subnet_id" {
description = "Subnet ID for Azure kubernetes nodes"
type = string
}

variable "node_count" {
description = "Number of nodes in the default node pool"
type = number
default = 1
}

variable "service_cidr" {
description = "Service CIDR"
type = string
default = "172.16.0.0/16"
}

variable "dns_service_ip" {
description = "DNS service IP"
type = string
default = "172.16.0.10"
}

variable "pod_cidr" {
description = "Pod CIDR"
type = string
default = "10.244.0.0/16"
}

variable "tags" {
description = "Resource tags"
type = map(string)
default = {}
}

variable "acr_id" {
description = "Azure Container Registry ID"
type = string
}

variable "log_analytics_workspace_id" {
description = "The ID of the Log Analytics Workspace for OMS Agent"
type = string
}

variable "authorized_ip_ranges" {
description = "List of authorized IP ranges for API server access"
type = list(string)
default = [
"10.244.0.0/16",
"172.16.0.0/16",
"10.0.0.0/16",
]
}
Loading