Terraform 코드를 사용하여 AGW 구성, 기존 VM 등록 및 NSG 정책 추가
- https://comengx.tistory.com/89 에서 구성한 내용에서 LB, LB 공인 IP 삭제 후 진행
- AGW 전용 SUBNET 생성 - azuredev-agw-subnet (사전 구성)
- 기존 subnet을 같이 사용했더니, agw 구성이 진행되면서, 구성되어 있는 vm이 모두 삭제 됨.
- terraform plan 진행 시 기존 리소스 삭제 안내가 있었는데,, 제대로 보지를 않음.;;;;
- 클라이언트 -> AGW 접속(공인 IP) -> VM 접속(사설 IP)
- 기존에 구성한 NSG에 HTTP 서비스 포트 추가
- 정책 추가 시 기존에 등록 된 정책과 규칙 번호가 중복되지 않도록 확인 필요
디렉토리 구조
각 파일의 내용
- 메인 구성 - main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "4.4.0"
}
}
}
variable "subscription_id" {}
variable "client_id" {}
variable "client_secret" {}
variable "tenant_id" {}
provider "azurerm" {
# Configuration options
features {}
subscription_id = var.subscription_id
client_id = var.client_id
client_secret = var.client_secret
tenant_id = var.tenant_id
}
# 기존 리소스 그룹 참조
data "azurerm_resource_group" "rg" {
name = var.resource_group_name
}
# 네트워크 모듈 호출
module "network" {
source = "./modules/network"
resource_group_name = data.azurerm_resource_group.rg.name
location = data.azurerm_resource_group.rg.location
vnet_name = var.vnet_name
subnet_name = var.subnet_name
}
# Application Gateway 모듈 호출
module "agw" {
source = "./modules/agw"
resource_group_name = data.azurerm_resource_group.rg.name
location = data.azurerm_resource_group.rg.location
subnet_id = module.network.subnet_id
backend_vm_ips = var.backend_vm_ips
}
# 보안 모듈 호출
module "security" {
source = "./modules/security"
resource_group_name = data.azurerm_resource_group.rg.name
nsg_name = var.nsg_name
agw_public_ip = module.agw.public_ip_address
}
- 변수 - variables.tf
variable "resource_group_name" {
description = "기존 리소스 그룹의 이름"
default = "azuredev-rg"
}
variable "vnet_name" {
description = "기존 VNET의 이름"
default = "azuredev-vnet"
}
variable "subnet_name" {
description = "기존 서브넷의 이름"
default = "azuredev-agw-subnet"
}
variable "nsg_name" {
description = "기존 NSG의 이름"
default = "azuredev-nsg"
}
variable "backend_vm_ips" {
description = "백엔드 VM의 사설 IP 목록"
type = list(string)
default = ["10.0.101.4", "10.0.101.5", "10.0.101.6"]
}
- 출력 - outputs.tf
output "agw_public_ip" {
description = "Application Gateway의 공용 IP 주소"
value = module.agw.public_ip_address
}
output "agw_backend_pool_ids" {
description = "Application Gateway 백엔드 풀 ID"
value = module.agw.backend_pool_ids
}
- 네트워킹 모듈 - modules/network/main.tf
# 기존 VNET 참조
data "azurerm_virtual_network" "vnet" {
name = var.vnet_name
resource_group_name = var.resource_group_name
}
# 기존 서브넷 참조
data "azurerm_subnet" "subnet" {
name = var.subnet_name
virtual_network_name = data.azurerm_virtual_network.vnet.name
resource_group_name = var.resource_group_name
}
- 네트워킹 모듈 변수 - modules/network/variables.tf
variable "resource_group_name" {
description = "리소스 그룹 이름"
type = string
}
variable "location" {
description = "Azure 지역"
type = string
}
variable "vnet_name" {
description = "기존 VNET 이름"
type = string
}
variable "subnet_name" {
description = "기존 서브넷 이름"
type = string
}
- 네트워킹 모듈 출력 - modules/networking/outputs.tf
output "subnet_id" {
description = "AGW 서브넷 ID"
value = data.azurerm_subnet.subnet.id
}
- AGW 모듈 - modules/agw/main.tf
# AGW를 위한 공용 IP 생성
resource "azurerm_public_ip" "agw_pip" {
name = "agw-pip"
resource_group_name = var.resource_group_name
location = var.location
allocation_method = "Static"
sku = "Standard"
}
# Application Gateway 생성
resource "azurerm_application_gateway" "agw" {
name = "azuredev-agw"
resource_group_name = var.resource_group_name
location = var.location
sku {
name = "Standard_v2"
tier = "Standard_v2"
capacity = 2
}
gateway_ip_configuration {
name = "my-gateway-ip-configuration"
subnet_id = var.subnet_id
}
frontend_port {
name = "http"
port = 80
}
frontend_ip_configuration {
name = "my-frontend-ip-configuration"
public_ip_address_id = azurerm_public_ip.agw_pip.id
}
backend_address_pool {
name = "my-backend-pool"
ip_addresses = var.backend_vm_ips
}
backend_http_settings {
name = "http"
cookie_based_affinity = "Disabled"
port = 80
protocol = "Http"
}
http_listener {
name = "http"
frontend_ip_configuration_name = "my-frontend-ip-configuration"
frontend_port_name = "http"
protocol = "Http"
}
request_routing_rule {
name = "rule1"
rule_type = "Basic"
http_listener_name = "http"
backend_address_pool_name = "my-backend-pool"
backend_http_settings_name = "http"
priority = 1
}
}
- AGW 모듈 변수 - modules/agw/variables.tf
variable "resource_group_name" {
description = "리소스 그룹 이름"
type = string
}
variable "location" {
description = "Azure 지역"
type = string
}
variable "subnet_id" {
description = "AGW 서브넷 ID"
type = string
}
variable "backend_vm_ips" {
description = "백엔드 VM의 사설 IP 목록"
type = list(string)
}
- AGW 모듈 출력 - modules/agw/outputs.tf
output "public_ip_address" {
description = "Application Gateway의 공용 IP 주소"
value = azurerm_public_ip.agw_pip.ip_address
}
output "backend_pool_ids" {
description = "Application Gateway 백엔드 풀 ID"
value = azurerm_application_gateway.agw.backend_address_pool[*].id
}
- 보안 모듈 - modules/security/main.tf
# 기존 NSG 참조
data "azurerm_network_security_group" "nsg" {
name = var.nsg_name
resource_group_name = var.resource_group_name
}
# AGW 관리 트래픽을 허용하는 NSG 규칙
resource "azurerm_network_security_rule" "allow_agw" {
name = "AllowAGWInbound"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "65200-65535"
source_address_prefix = "GatewayManager"
destination_address_prefix = "*"
resource_group_name = var.resource_group_name
network_security_group_name = data.azurerm_network_security_group.nsg.name
}
# HTTP 트래픽을 허용하는 NSG 규칙
resource "azurerm_network_security_rule" "allow_http" {
name = "AllowHTTPInbound"
priority = 120
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "Internet"
destination_address_prefix = var.agw_public_ip
resource_group_name = var.resource_group_name
network_security_group_name = data.azurerm_network_security_group.nsg.name
}
- 보안 모듈 변수 - modules/security/variables.tf
variable "resource_group_name" {
description = "리소스 그룹 이름"
type = string
}
variable "nsg_name" {
description = "기존 NSG 이름"
type = string
}
variable "agw_public_ip" {
description = "Application Gateway의 공용 IP 주소"
type = string
}
- 보안 모듈 출력 - modules/security/outputs.tf
없음
VM 리소스 생성
1. 초기화
terraform init
2. 계획 확인
terraform plan
3. 리소스 생성
terraform apply
VM 리소스 확인
접속 테스트