terraform

Terraform을 이용해 Azure 인프라 구축하기(dns, db server(mysql))

kkuniyo 2025. 3. 30. 20:50
반응형

 

Terraform으로 Azure DNS와 DB서버 구성하기

 

구성 목표 및 Terraform 파일 소개

이번 실습은 크게 다음과 같은 세 가지 리소스를 Terraform으로 구성합니다.

  • DNS Zone (16_dns.tf)
  • DNS Record (17_dnsrecord.tf)
  • Database Server (20_db.tf)

 

1. Azure DNS Zone 생성 (16_dns.tf)

# Public DNS Zone 및 A 레코드 생성
# - 외부 도메인 이름(test1 ~ test4)을 생성하고, 각 도메인에 대해
#   "www" A 레코드를 생성하여 지정된 Public IP 주소(예: Application Gateway IP)를 매핑합니다.

# DNS Zone 1: test1
resource "azurerm_dns_zone" "main_dns" {
  name                = "test1"                              # 도메인 이름을 test1으로 변경
  resource_group_name = azurerm_resource_group.main_rg.name
}

# DNS Zone 2: test2
resource "azurerm_dns_zone" "main_dns1" {
  name                = "test2"                              # 도메인 이름을 test2로 변경
  resource_group_name = azurerm_resource_group.main_rg.name
}

# DNS Zone 3: test3
resource "azurerm_dns_zone" "main_dns2" {
  name                = "test3"                              # 도메인 이름을 test3로 변경
  resource_group_name = azurerm_resource_group.main_rg.name
}

# DNS Zone 4: test4
resource "azurerm_dns_zone" "main_dns3" {
  name                = "test4"                              # 도메인 이름을 test4로 변경
  resource_group_name = azurerm_resource_group.main_rg.name
}

🟢 Step 2. DNS 레코드 등록 (17_dnsrecord.tf)

DNS Zone을 생성한 후에는 실제로 사용할 DNS 레코드를 설정해야 합니다. 예시 코드는 다음과 같습니다.

# DNS A 레코드: Root 및 www 레코드 (DNS Zone 1)
# - "main_dns" DNS Zone에 대해 루트 도메인("@")과 "www" 서브도메인에 동일한 Public IP 주소를 매핑합니다.

# "www" 호스트에 대한 A 레코드 (DNS Zone: main_dns)
resource "azurerm_dns_a_record" "main_www" {
  name                = "www"                                          # www 서브도메인
  zone_name           = azurerm_dns_zone.main_dns.name                 # 대상 DNS Zone (예: test1)
  resource_group_name = azurerm_resource_group.main_rg.name            # 리소스 그룹 이름
  ttl                 = 300                                            # TTL(Time To Live) 설정 (초)
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]   # 매핑할 Public IP 주소
}


resource "azurerm_dns_a_record" "main_root" {
  name                = "@"                                          
  zone_name           = azurerm_dns_zone.main_dns.name               
  resource_group_name = azurerm_resource_group.main_rg.name          
  ttl                 = 300                                          
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]   
}

resource "azurerm_dns_a_record" "main_www1" {
  name                = "www"                                        
  zone_name           = azurerm_dns_zone.main_dns1.name            
  resource_group_name = azurerm_resource_group.main_rg.name           
  ttl                 = 300                                            
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]   
}


resource "azurerm_dns_a_record" "main_root1" {
  name                = "@"                                          
  zone_name           = azurerm_dns_zone.main_dns1.name               
  resource_group_name = azurerm_resource_group.main_rg.name        
  ttl                 = 300                                          
  records             = [azurerm_public_ip.main_appgw_ip.ip_address] 
}

resource "azurerm_dns_a_record" "main_www2" {
  name                = "www"                                      
  zone_name           = azurerm_dns_zone.main_dns2.name               
  resource_group_name = azurerm_resource_group.main_rg.name        
  ttl                 = 300                                           
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]  
}

resource "azurerm_dns_a_record" "main_root2" {
  name                = "@"                                         
  zone_name           = azurerm_dns_zone.main_dns2.name            
  resource_group_name = azurerm_resource_group.main_rg.name          
  ttl                 = 300                                          
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]  
}

resource "azurerm_dns_a_record" "main_www3" {
  name                = "www"                                       
  zone_name           = azurerm_dns_zone.main_dns3.name               
  resource_group_name = azurerm_resource_group.main_rg.name           
  ttl                 = 300                                         
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]   
}

resource "azurerm_dns_a_record" "main_root3" {
  name                = "@"                                           
  zone_name           = azurerm_dns_zone.main_dns3.name             
  resource_group_name = azurerm_resource_group.main_rg.name          
  ttl                 = 300                                          
  records             = [azurerm_public_ip.main_appgw_ip.ip_address]  
}

🟢 Step 3. DB 서버 구축 및 구성 (20_db.tf)

# Private DNS Zone 및 가상 네트워크 링크 설정
# - Azure MySQL의 Private Link에 대한 Private DNS Zone을 생성하고,
#   해당 Private DNS Zone을 가상 네트워크(main_vnet)에 연결합니다.

resource "azurerm_private_dns_zone" "main_pdns" {
  name                = "privatelink.mysql.database.azure.com"  # Private DNS Zone 이름 (Azure MySQL 전용)
  resource_group_name = azurerm_resource_group.main_rg.name
}

resource "azurerm_private_dns_zone_virtual_network_link" "main_pdns_vnet_link" {
  name                  = "main-pdns-vnetzone.com"             
  resource_group_name   = azurerm_resource_group.main_rg.name
  private_dns_zone_name = azurerm_private_dns_zone.main_pdns.name 
  virtual_network_id    = azurerm_virtual_network.main_vnet.id    
}

# MySQL Flexible Server 생성
# - Azure MySQL Flexible Server를 생성하며, 관리자 계정과 SKU, 버전을 설정합니다.

resource "azurerm_mysql_flexible_server" "main_mysql" {
  name                   = "main-mysql"                       
  resource_group_name    = azurerm_resource_group.main_rg.name
  location               = azurerm_resource_group.main_rg.location
  administrator_login    = "main"                               # 관리자 사용자명 변경
  administrator_password = "It12345!"                           # 관리자 비밀번호
  sku_name               = "B_Standard_B1ms"                    # SKU 이름
  version                = "8.0.21"                             # MySQL 버전
}

# Private Endpoint 생성 (MySQL Flexible Server)
# - MySQL 서버에 대한 Private Endpoint를 생성하여, 지정된 서브넷(main_db) 내에서
#   Private Link 연결을 구성하고, Private DNS Zone과 연동합니다.

resource "azurerm_private_endpoint" "main_mysql_pe" {
  name                = "main-mysql-pe"                        # Private Endpoint 이름 변경
  location            = azurerm_resource_group.main_rg.location
  resource_group_name = azurerm_resource_group.main_rg.name
  subnet_id           = azurerm_subnet.main_db.id               # 연결할 DB 서브넷

  private_service_connection {
    name                           = "mysql"                      
    private_connection_resource_id = azurerm_mysql_flexible_server.main_mysql.id  
    subresource_names              = ["mysqlServer"]           
    is_manual_connection           = false                      
  }
  
  private_dns_zone_group {
    name                 = "mysql-dns-zone-group"           
    private_dns_zone_ids = [azurerm_private_dns_zone.main_pdns.id] 
  }
}

# MySQL Flexible Server 구성 변경
# - MySQL 서버의 구성 항목(require_secure_transport)을 변경합니다.

resource "azurerm_mysql_flexible_server_configuration" "main_mysql_config" {
  name                = "require_secure_transport"             
  resource_group_name = azurerm_resource_group.main_rg.name
  server_name         = azurerm_mysql_flexible_server.main_mysql.name  
  value               = "OFF"                               
}


# MySQL Flexible Database 생성
# - MySQL 서버 내에 "wordpress" 데이터베이스를 생성합니다.

resource "azurerm_mysql_flexible_database" "main_mysql_db" {
  name                = "wordpress"                         
  resource_group_name = azurerm_resource_group.main_rg.name
  server_name         = azurerm_mysql_flexible_server.main_mysql.name  
  charset             = "utf8"                            
  collation           = "utf8_general_ci"               
}

적용 사례 및 이점

Terraform으로 DNS 및 DB 서버를 관리하면 다음과 같은 이점이 있습니다.

  • 효율성: 반복적 작업을 줄이고 일관된 리소스 배포가 가능합니다.
  • 확장성: 코드 한 줄로 리소스를 신속하게 추가 및 확장할 수 있습니다.
  • 안정성: 수동 작업에서 발생할 수 있는 오류를 최소화하여 인프라 안정성을 높입니다.

 

 

이상으로 이번 글을 마칩니다. 궁금한 부분은 댓글을 통해 언제든 질문해주세요 😊

반응형