terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0.2"
}
}
required_version = ">= 1.1.0"
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
Code 의미 prevent_deletion_if_contains_resources = false
리소스 그룹을 deletion
할 때 안에있는 리소스들을 지우지 못하게 방지 할 것인지에 대해서false
해주겠다는 의미
resource "azurerm_resource_group" "rg" {
name = "wordpressrg"
location = "koreacentral"
}
Azure에서는 AWS와 다르게 가장 외곽에
리소스 그룹
이 존재한다. 네트워크 구성도 이 리소스 그룹 안에서 이루어진다. 다만, 리소스 그룹이 다르다고 하여도 AWS에서 VPC가 다른것 처럼 작동하지 않고 그냥 리소스를 담아놓는 그룹이므로 전혀 상관없이 서로 다른 리소스 그룹안에 있어도 통신이 가능하다.
네트워크 | address_prefixes |
---|---|
virtual_network | 20.0.0.0/16 |
subnet.frontend | 20.0.0.0/24 |
subnet.backend | 20.0.10.0/24 |
subnet.database | 20.0.20.0/24 |
resource "azurerm_virtual_network" "wordpressvn" {
name = "wpvn"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["20.0.0.0/16"]
}
resource "azurerm_subnet" "frontend" {
name = "frontendserver"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.wordpressvn.name
address_prefixes = ["20.0.0.0/24"]
}
resource "azurerm_subnet" "backend" {
name = "backendserver"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.wordpressvn.name
address_prefixes = ["20.0.10.0/24"]
}
resource "azurerm_subnet" "dbserver" {
name = "dbserver"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.wordpressvn.name
address_prefixes = ["20.0.20.0/24"]
}
서브넷주소의 prefix를 편의상 큰 범위로 잡아놨다. 이후에 적절한 서브넷 범위로 수정이 필요해 보인다.
resource "azurerm_network_interface" "db" {
name = "dbif"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "dbconf"
subnet_id = azurerm_subnet.dbserver.id
private_ip_address_allocation = "Dynamic"
}
}
resource "azurerm_linux_virtual_machine" "db" {
name = "databasesv"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.db.id]
size = "Standard_DS1_v2"
admin_username = "centos"
custom_data = "IyEvYmluL2Jhc2gNCnN1ZG8gc2V0ZW5mb3JjZSAwDQpzZXRlbmZvcmNlIDA="
source_image_id = "/subscriptions/8638e904-9ff3-48e8-85ff-7f37869d4e0c/resourceGroups/wordpress/providers/Microsoft.Compute/galleries/dbserver/images/dbserver"
os_disk {
caching = "ReadWrite"
storage_account_type = "StandardSSD_LRS"
}
admin_ssh_key {
username = "centos"
public_key = file("~/.ssh/id_rsa.pub")
}
user_data = "IyEvYmluL2Jhc2gNCnN1ZG8gc2V0ZW5mb3JjZSAwDQpzZXRlbmZvcmNlIDA="}
Code
의미
source_image_id
데이터베이스 가상머신을 시작할 이미지의 주소를 정의하는 부분이다. 해당 id는 리소스그룹/리소스/이미지버전/속성/리소스 ID 에서 확인할 수 있다.
custom_data
Azure에서는 AWS와 다르게 사용자 데이터를 입력할 때 Base64 인코딩을 사용한다. 인코딩한 내용은 #!bin/bash setenforce 0 sudo setenforce 0 이다.
user_data
custom_data와의 차이는 정확히 모르겠지만 둘 다 정의해 주었을 때 제대로 작동하는 것을 확인했다.
public_key = file("~/.ssh/id_rsa.pub")
terraform을 실행시키는 가상머신에서 만든 공개키를 붙여넣어서 나중에 ssh접속이 가능하게 해줄 수 있다. 주의할 점으로는 password방식과 공개키 방식중에 하나는 꼭 정의되어야 한다는 것이다.
resource "azurerm_network_security_group" "dbsg" {
name = "database-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "dbin"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "3306"
source_address_prefix = "20.0.0.0/16"
destination_address_prefix = "*"
}
security_rule {
name = "dbbastionin"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
현재는 보안그룹이 너무 많은 주소범위에 대해서 열려있는 상태이다.
22번 포트는 bastionhost
에 대해서만 그리고3306포트
에 대해서는 webserver 인스턴스들이 존재하는backend 서브넷
에 대해서만 열어주도록 변경해주어야 한다.
resource "azurerm_subnet_network_security_group_association" "dbsga" {
subnet_id = azurerm_subnet.dbserver.id
network_security_group_id = azurerm_network_security_group.dbsg.id
}
보안그룹을 만들었으니 보안그룹을 서브넷에 할당시킨다. 그러면 해당 서브넷에서 만들어진 리소스들이 보안그룹을 모두 할당받는다.
resource "azurerm_network_interface" "web" {
name = "webif"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "webconf"
subnet_id = azurerm_subnet.backend.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.web.id
}
}
resource "azurerm_public_ip" "web" {
name = "myPublicIP"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
웹서버 가상머신은 웹사이트를 호스팅하기 위해 외부에서 접속할
공개 IP
가 필요하다.공개IP
리소스를 미리 선언하고 이 리소스의id
를 네트워크 인터페이스에 참조시킨다. 그러면 네트워크 인터페이스가 참조하는 서브넷 즉, subnet.backend에서 생성되는 모든 가상머신들은공개IP
를 가지게된다.
resource "azurerm_linux_virtual_machine" "web" {
name = "websv"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.web.id]
size = "Standard_DS1_v2"
admin_username = "centos"
custom_data = "IyEvYmluL2Jhc2gNCnN1ZG8gc2V0ZW5mb3JjZSAwDQpzZXRlbmZvcmNlIDA
="
source_image_id = "/subscriptions/8638e904-9ff3-48e8-85ff-7f37869d4e0c/res
ourceGroups/wordpress/providers/Microsoft.Compute/galleries/webfinal/images/
webfinal/versions/0.0.1"
os_disk {
caching = "ReadWrite"
storage_account_type = "StandardSSD_LRS"
}
admin_ssh_key {
username = "centos"
public_key = file("~/.ssh/id_rsa.pub")
}
user_data = "IyEvYmluL2Jhc2gNCnN1ZG8gc2V0ZW5mb3JjZSAwDQpzZXRlbmZvcmNlIDA="
}
웹서버용 가상머신의 구성도 데이터베이스와 비슷하다. 다만 당연히 참조하는 이미지가 다르다.
resource "azurerm_network_security_group" "websg" {
name = "web-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "webin"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "dbbastionin"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
웹서버로 들어오는 80포트에 대한 인바운드를 열어주었다. 그리고 ssh 접속을 위한 22번 포트를 열어주었는데, 이후에 배스천 호스트에서만 접속할 수 있게 변경해주어야한다.
resource "azurerm_subnet_network_security_group_association" "websga" {
subnet_id = azurerm_subnet.backend.id
network_security_group_id = azurerm_network_security_group.websg.id
}
/홈/리소스 그룹/wordpressrg/websv/개요
에서 [공용 IP 주소]/wordpress
로 접속하면 데이터베이스 인스턴스를 참조하는 웹서버가 호스팅하는 페이지로 접속되는 것을 확인 할 수 있다.
4기쪽은 azure도 배우고 테라폼으로 인프라프로비저닝하는것도 다했나요? 부럽네요ㅠ