본문 바로가기
DevOps

Terraform (Azure)

by 이강복 2023. 1. 18.

public_key.tf

resource "azurerm_ssh_public_key" "ssh_key" {
  name = "${var.prefix}-key"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  public_key = file("${var.pub_key_path}")
}

main.tf

provider "azurerm" {
  features {}
  skip_provider_registration = true
}

resource_group.tf

resource "azurerm_resource_group" "rg1" {
  name = "${var.rg1}-rg"
  location = "${var.location1}"
}

resource "azurerm_resource_group" "rg2" {
  name = "${var.rg2}-rg"
  location = "${var.location1}"
}

resource "azurerm_resource_group" "rg3" {
  name = "${var.rg3}-rg"
  location = "${var.location1}"
}

security_group.tf

resource "azurerm_network_security_group" "nsg" {
  name = "${var.rg1}-nsg"
  location = "${var.location1}"
  resource_group_name = azurerm_resource_group.rg1.name
}

resource "azurerm_network_security_rule" "fw1" {
  name                        = "${var.prefix}-fw1"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_ranges      = ["22"]
  source_address_prefix       = "Internet"
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg1.name
  network_security_group_name = azurerm_network_security_group.nsg.name
}

resource "azurerm_network_security_rule" "fw2" {
  name                        = "${var.prefix}-fw2"
  priority                    = 200
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_ranges      = ["8080"]
  source_address_prefix       = "Internet"
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = azurerm_resource_group.rg1.name
  network_security_group_name = azurerm_network_security_group.nsg.name
}

virtual_network.tf

resource "azurerm_virtual_network" "vnet1" {
  name = "${var.vnet1}-vnet"
  location = "${var.location1}"
  resource_group_name = azurerm_resource_group.rg1.name
  address_space = ["${var.vnet_address}"]
}

subnet.tf

resource "azurerm_subnet" "subnet1" {
  name = "${var.subnet1}-subnet"
  address_prefixes = ["${var.subnet1_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet2" {
  name = "${var.subnet2}-subnet"
  address_prefixes = ["${var.subnet2_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet3" {
  name = "${var.subnet3}-subnet"
  address_prefixes = ["${var.subnet3_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet4" {
  name = "${var.subnet4}-subnet"
  address_prefixes = ["${var.subnet4_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet5" {
  name = "${var.subnet5}-subnet"
  address_prefixes = ["${var.subnet5_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet6" {
  name = "${var.subnet6}"
  address_prefixes = ["${var.subnet6_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet7" {
  name = "${var.subnet7}"
  address_prefixes = ["${var.subnet7_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

resource "azurerm_subnet" "subnet8" {
  name = "${var.subnet8}"
  address_prefixes = ["${var.subnet8_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
  service_endpoints = ["Microsoft.Storage"]

  delegation {
    name = "fs"

    service_delegation {
      name = "Microsoft.DBforMySQL/flexibleServers"
      actions = [ "Microsoft.Network/virtualNetworks/subnets/join/action" ]
    }
  }
}

resource "azurerm_subnet" "subnet9" {
  name = "${var.subnet9}"
  address_prefixes = ["${var.subnet9_address}"]
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_name = azurerm_virtual_network.vnet1.name
}

network_interface.tf

# resource "azurerm_network_interface" "nic_vm1" {
#   name = "${var.rg1}-nic-vm1"
#   location = "${var.location1}"
#   resource_group_name = azurerm_resource_group.rg1.name

#   ip_configuration {
#     name = "internal"
#     private_ip_address_allocation = "${var.type2}"
#     subnet_id = azurerm_subnet.subnet1.id
#     public_ip_address_id = azurerm_public_ip.pub_ip1.id
#   }
# }

# resource "azurerm_network_interface_security_group_association" "nic1" {
#   network_interface_id = azurerm_network_interface.nic_vm1.id
#   network_security_group_id = azurerm_network_security_group.nsg.id
# }

resource "azurerm_network_interface" "nic_vm2" {
  name = "${var.rg1}-nic-vm2"
  location = "${var.location1}"
  resource_group_name = azurerm_resource_group.rg1.name

  ip_configuration {
    name = "internal"
    private_ip_address_allocation = "${var.type2}"
    subnet_id = azurerm_subnet.subnet1.id
    public_ip_address_id = azurerm_public_ip.pub_ip4.id
  }
}

resource "azurerm_network_interface_security_group_association" "nic2" {
  network_interface_id = azurerm_network_interface.nic_vm2.id
  network_security_group_id = azurerm_network_security_group.nsg.id
}

vm.tf

# resource "azurerm_virtual_machine" "vm1" {
#   name = "${var.rg1}-vm1"
#   resource_group_name = azurerm_resource_group.rg1.name
#   location = "${var.location1}"
#   vm_size = "${var.vm_size}"
#   delete_os_disk_on_termination = true
#   network_interface_ids = [
#     azurerm_network_interface.nic_vm1.id
#   ]
  

#   storage_os_disk {
#     name = "${var.rg1}-vm1-os-disk"
#     caching = "ReadWrite"
#     create_option = "FromImage"
#     managed_disk_type = "${var.disk_type1}"
#   }

#   storage_image_reference {
#     publisher = "OpenLogic"
#     offer = "CentOS"
#     sku = "7.5"
#     version = "latest"
#   }

#   os_profile {
#     computer_name = "${var.prefix}-vm1"
#     admin_username = "${var.admin_username}"
#     custom_data = file("./nginx.sh")
#   }

#   os_profile_linux_config {
#     disable_password_authentication = true

#     ssh_keys {
#       path = "${var.ssh_key_path}"
#       key_data = azurerm_ssh_public_key.ssh_key.public_key
#     }
#   }
# }

resource "azurerm_virtual_machine" "vm2" {
  name = "${var.rg1}-vm2"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  vm_size = "${var.vm_size}"
  delete_os_disk_on_termination = true
  network_interface_ids = [
    azurerm_network_interface.nic_vm2.id
  ]
  

  storage_os_disk {
    name = "${var.rg1}-vm2-os-disk"
    caching = "ReadWrite"
    create_option = "FromImage"
    managed_disk_type = "${var.disk_type1}"
  }

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "22.04-LTS"
    version   = "latest"
  }
  
  os_profile {
    computer_name = "${var.prefix}-vm2"
    admin_username = "${var.admin_username}"
    custom_data = <<-EOF
#!/bin/bash
# nginx
sudo apt update
sudo apt-get upgrade -y
sudo apt-get install -y docker.io
sudo git clone https://github.com/kangbock/jenkins.git
sudo sh jenkins/nginx/az_cli.sh
sudo sh jenkins/nginx/mysql.sh
    EOF
  }

  os_profile_linux_config {
    disable_password_authentication = true

    ssh_keys {
      path = "${var.ssh_key_path}"
      key_data = azurerm_ssh_public_key.ssh_key.public_key
    }
  }
}

WAF.tf

resource "azurerm_web_application_firewall_policy" "WAF" {
  name                = "WAF"
  resource_group_name = azurerm_resource_group.rg1.name
  location            = "${var.location1}"

  custom_rules {
    name      = "Rule1"
    priority  = 1
    rule_type = "MatchRule"

    match_conditions {
      match_variables {
        variable_name = "RemoteAddr"
      }

      operator           = "IPMatch"
      negation_condition = true
      match_values       = ["192.168.1.0/24", "10.0.0.0/16", "${var.cp_ip}"]
    }

    action = "Block"
  }
/*
  custom_rules {
    name      = "Rule2"
    priority  = 2
    rule_type = "MatchRule"

    match_conditions {
      match_variables {
        variable_name = "RemoteAddr"
      }

      operator           = "IPMatch"
      negation_condition = false
      match_values       = ["192.168.1.0/24"]
    }

    match_conditions {
      match_variables {
        variable_name = "RequestHeaders"
        selector      = "UserAgent"
      }

      operator           = "Contains"
      negation_condition = false
      match_values       = ["Windows"]
    }

    action = "Block"
  }
*/
  policy_settings {
    enabled                     = true
    mode                        = "Prevention"
    request_body_check          = true
    file_upload_limit_in_mb     = 100
    max_request_body_size_in_kb = 128
  }

  managed_rules {
    exclusion {
      match_variable          = "RequestHeaderNames"
      selector                = "x-company-secret-header"
      selector_match_operator = "Equals"
    }
    exclusion {
      match_variable          = "RequestCookieNames"
      selector                = "too-tasty"
      selector_match_operator = "EndsWith"
    }

    managed_rule_set {
      type    = "OWASP"
      version = "3.2"
      rule_group_override {
        rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT"
        rule {
          id      = "920300"
          enabled = true
          action  = "Log"
        }

        rule {
          id      = "920440"
          enabled = true
          action  = "Block"
        }
      }
    }
  }
}

application_gateway.tf

resource "azurerm_application_gateway" "app_gw" {
  name = "${var.app_gw}"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  firewall_policy_id = azurerm_web_application_firewall_policy.WAF.id

  sku {
    name = "${var.sku_name}"
    tier = "${var.sku_tier}"
    capacity = 1
  }

  gateway_ip_configuration {
    name = "${var.gw_ip}"
    subnet_id = azurerm_subnet.subnet5.id
  }

  frontend_port {
    name = local.frontend_port_name
    port = 80
  }

  frontend_ip_configuration {
    name = local.frontend_ip_configuration_name
    public_ip_address_id = azurerm_public_ip.pub_ip2.id
  }

  backend_address_pool {
    name = local.backend_address_pool_name
    ip_addresses = [ "20.200.234.83" ]
  }

  backend_http_settings {
    name = local.http_setting_name
    cookie_based_affinity = "Disabled"
    path = ""
    port = 80
    protocol = "Http"
    request_timeout = 60
  }

  http_listener {
    name = local.listener_name
    frontend_ip_configuration_name = local.frontend_ip_configuration_name
    frontend_port_name = local.frontend_port_name
    protocol = "Http"
  }

  request_routing_rule {
    name = local.request_routing_rule_name
    rule_type = "${var.rule_type}"
    priority = 100
    http_listener_name = local.listener_name
    backend_address_pool_name = local.backend_address_pool_name
    backend_http_settings_name = local.http_setting_name
  }
}

resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "app_gw_back" {
  network_interface_id = azurerm_network_interface.nic_vm2.id
  ip_configuration_name = "internal"
  backend_address_pool_id = tolist(azurerm_application_gateway.app_gw.backend_address_pool).0.id
}

nat_gateway.tf

resource "azurerm_nat_gateway" "nat_gw" {
  name = "${var.rg1}-NAT-GW"
  location = azurerm_resource_group.rg1.location
  resource_group_name = azurerm_resource_group.rg1.name
}

resource "azurerm_nat_gateway_public_ip_association" "nat_gw_pub" {
  nat_gateway_id       = azurerm_nat_gateway.nat_gw.id
  public_ip_address_id = azurerm_public_ip.pub_ip5.id
}

resource "azurerm_subnet_nat_gateway_association" "ngw_aso" {
  subnet_id      = azurerm_subnet.subnet1.id
  nat_gateway_id = azurerm_nat_gateway.nat_gw.id
}

output "ngw_ip" {
  value = azurerm_public_ip.pub_ip5.public_ip_prefix_id
}

route_table.tf

resource "azurerm_route_table" "nrt" {
  name = "${var.rg1}-nrt"
  location = azurerm_resource_group.rg1.location
  resource_group_name = azurerm_resource_group.rg1.name
  disable_bgp_route_propagation = false
  depends_on = [
    azurerm_firewall.fw
  ]

  route {
    name = "${var.rg1}-nrt"
    address_prefix = "0.0.0.0/0"
    next_hop_type = "Internet"
    # next_hop_type = "VirtualAppliance"
    # next_hop_in_ip_address = "10.0.6.4" //azure firewall
  }
}

azure_firewall.tf

resource "azurerm_firewall" "fw" {
  name = "${var.rg1}-fw"
  location = azurerm_resource_group.rg1.location
  resource_group_name = azurerm_resource_group.rg1.name
  sku_name = "AZFW_VNet"
  sku_tier = "Standard"

  ip_configuration {
    name = "configuration"
    subnet_id = azurerm_subnet.subnet7.id
    public_ip_address_id = azurerm_public_ip.pub_ip6.id
  }
}

firewall_policy.tf

# resource "azurerm_firewall_policy" "fw_policy" {
#   name = "${var.rg1}-fw-policy"
#   resource_group_name = azurerm_resource_group.rg1.name
#   location = azurerm_resource_group.rg1.location
# }

resource "azurerm_firewall_network_rule_collection" "fw_network" {
  name                = "${var.rg1}-fw-network"
  azure_firewall_name = azurerm_firewall.fw.name
  resource_group_name = azurerm_resource_group.rg1.name
  priority            = 100
  action              = "Allow"

  rule {
    name = "testrule"
    source_addresses = [ "${var.cp_ip}" ]
    destination_ports = [ "22", "8080"]
    destination_addresses = [ "10.0.0.0/16" ]
    protocols = [ "TCP", "UDP", ]
  }

  rule {
        name = "testrule2"
    source_addresses = [ "*" ]
    destination_ports = [ "80"]
    destination_addresses = [ "10.0.0.0/16" ]
    protocols = [ "TCP", "UDP", ]
  }
}

dns.tf

resource "azurerm_dns_zone" "dns" {
  name = "kb97.xyz"
  resource_group_name = azurerm_resource_group.rg1.name
  depends_on = [
    azurerm_application_gateway.app_gw
  ]
}

resource "azurerm_dns_a_record" "ns" {
  name = "@"
  zone_name = azurerm_dns_zone.dns.name
  resource_group_name = azurerm_resource_group.rg1.name
  ttl = 300
  target_resource_id = azurerm_public_ip.pub_ip2.id
}

resource "azurerm_dns_a_record" "ns1" {
  name = "ns1"
  zone_name = azurerm_dns_zone.dns.name
  resource_group_name = azurerm_resource_group.rg1.name
  ttl = 300
  target_resource_id = azurerm_public_ip.pub_ip2.id
}

resource "azurerm_dns_a_record" "www" {
  name = "www"
  zone_name = azurerm_dns_zone.dns.name
  resource_group_name = azurerm_resource_group.rg1.name
  ttl = 300
  target_resource_id = azurerm_public_ip.pub_ip2.id
}

resource "azurerm_dns_a_record" "jenkins" {
  name = "jenkins"
  zone_name = azurerm_dns_zone.dns.name
  resource_group_name = azurerm_resource_group.rg1.name
  ttl = 300
  target_resource_id = azurerm_public_ip.pub_ip4.id
}

private_dns.tf

resource "azurerm_private_dns_zone" "private_dns" {
  name = "${var.rg1}.mysql.database.azure.com"
  resource_group_name = azurerm_resource_group.rg1.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "private_dns_vnet_link" {
  name = "private-dns-vnet-link"
  private_dns_zone_name = azurerm_private_dns_zone.private_dns.name
  resource_group_name = azurerm_resource_group.rg1.name
  virtual_network_id = azurerm_virtual_network.vnet1.id
}

mysql_flexible_server.tf

resource "azurerm_mysql_flexible_server" "mysql_fs" {
  location = azurerm_resource_group.rg1.location
  resource_group_name = azurerm_resource_group.rg1.name
  name = "${var.rg1}-mysql-fs"
  administrator_login = "${var.db_id}"
  administrator_password = "${var.db_pw}"
  backup_retention_days = 7
  delegated_subnet_id = azurerm_subnet.subnet8.id
  geo_redundant_backup_enabled = false
  private_dns_zone_id = azurerm_private_dns_zone.private_dns.id
  sku_name = "GP_Standard_D2ds_v4"
  version = "8.0.21"
  zone = "1"

  high_availability {
    mode = "ZoneRedundant"
    standby_availability_zone = "2"
  }

  maintenance_window {
    day_of_week = 0
    start_hour = 8
    start_minute = 0
  }

  storage {
    iops = 360
    size_gb = 20
  }

  depends_on = [
    azurerm_private_dns_zone_virtual_network_link.private_dns_vnet_link
  ]
}

aks(azure CNI).tf

resource "azurerm_kubernetes_cluster" "aks" {
  name = "${var.rg1}-aks"
  location = "${var.location1}"
  resource_group_name = azurerm_resource_group.rg1.name
  dns_prefix = "${var.rg1}-dns"

  default_node_pool {
    name = "default"
    node_count = 1
    vm_size = "${var.vm_size}"
    vnet_subnet_id = azurerm_subnet.subnet9.id
  }

  identity {
    type = "SystemAssigned"
  }

  network_profile {
    network_plugin = "azure"
    network_policy = "azure"
    service_cidr = "10.224.0.0/12"
    docker_bridge_cidr = "172.17.0.1/16"
    dns_service_ip = "10.224.0.10"
  }
}


output "client_certificate" {
  value = azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate
  sensitive = true
}

output "kube_config" {
  value = azurerm_kubernetes_cluster.aks.kube_config_raw
  sensitive = true
}

public_ip.tf

# resource "azurerm_public_ip" "pub_ip1" { // vm1
#   name = "${var.pub_ip1}"
#   resource_group_name = azurerm_resource_group.rg1.name
#   location = "${var.location1}"
#   allocation_method = "${var.type1}"
#   sku = "Standard"
# }

resource "azurerm_public_ip" "pub_ip2" {  // application gateway
  name = "${var.pub_ip2}"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  allocation_method = "${var.type1}"
  sku = "Standard"
}

# resource "azurerm_public_ip" "pub_ip3" { // vpn
#   name = "${var.pub_ip3}"
#   resource_group_name = azurerm_resource_group.rg1.name
#   location = "${var.location1}"
#   allocation_method = "${var.type2}"
# }

resource "azurerm_public_ip" "pub_ip4" { // vm2
  name = "${var.pub_ip4}"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  allocation_method = "${var.type1}"
  sku = "Standard"
}

resource "azurerm_public_ip" "pub_ip5" { // nat
  name = "${var.pub_ip5}"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  allocation_method = "${var.type1}"
  sku = "Standard"
}

resource "azurerm_public_ip" "pub_ip6" { // firewall
  name = "${var.pub_ip6}"
  resource_group_name = azurerm_resource_group.rg1.name
  location = "${var.location1}"
  allocation_method = "${var.type1}"
  sku = "Standard"
}


# output "pub_ip1" {
#   value = azurerm_public_ip.pub_ip1.ip_address
# }

output "pub_ip2" {
  value = azurerm_public_ip.pub_ip2.ip_address
}

output "pub_ip4" {
  value = azurerm_public_ip.pub_ip4.ip_address
}

output "pub_ip5" {
  value = azurerm_public_ip.pub_ip5.ip_address
}

output "pub_ip6" {
  value = azurerm_public_ip.pub_ip6.ip_address
}

 

'DevOps' 카테고리의 다른 글

Harbor  (1) 2023.05.23
ArgoCD Image Updater (현재 Beta 버전)  (0) 2023.02.24
Helm chart / kustomize  (0) 2023.02.24
CI/CD (Argo CD)  (0) 2023.01.31
CI/CD (Jenkins)  (0) 2023.01.18