Cloudest - 블로그 이사했습니다
노션으로 블로그를 옮겼습니다.
흥미로운 포스팅이 올라옵니다!
cloudest.oopy.io
🛠
준비물 :
1. 자신 소유의 도메인
2. AWS, Azure, GCP 계정
3. 테라폼 사용가능한 WSL2 (EC2같은 다른 리눅스도 가능하다. Ubuntu 18.04 or 20.04 추천)
1. 자신 소유의 도메인
2. AWS, Azure, GCP 계정
3. 테라폼 사용가능한 WSL2 (EC2같은 다른 리눅스도 가능하다. Ubuntu 18.04 or 20.04 추천)
멀티 클라우드
- 멀티 클라우드는 2개 이상의 클라우드 플랫폼에서 하나의 서비스를 운영하는 것
- 한가지 플랫폼에 Lock-In 되는 것을 방지할 수 있다.
- 여러 플랫폼의 경쟁력있는 서비스를 골라서 사용할 수 있다.
- 정말 만약의 사태에 한쪽 클라우드 플랫폼 전체적인 장애 발생시 더 높은 가용성을 제공할 수 있다.
시작 전
- AWS는 많이 사용해보았지만 Azure와 Gcp는 이번이 처음 사용이다.
- 개인 도메인이 없다면 Freenom [프리놈]과같은 사이트 통해 무료로 도메인을 대여할 수 있다고 한다.
GCP 회원가입 안 넘어가질 때
- 구글 로그인 된 상태로 https://console.cloud.google.com/ 해당 주소로 접속하면 아래와 같은 화면이 나온다.
- 구글 로그인 된 상태로 https://console.cloud.google.com/ 해당 주소로 접속하면 아래와 같은 화면이 나온다.
시행착오 : 이번 실습을 진행하면서 겪은 시행착오와 해결방법등을 적어두었다. 본문 내용들은 해결이 완료된 후 수정된 내용들이다.
💡변수를 제대로 인식하지 못하는 경우가 있어서 실습의 완성을 위해 변수대신에 직접 값을 입력한 부분들이 종종 있다.1. Azure CLI 환경 구성 - 해결
- 아래 코드 실행
apt update apt install azure-cli
- WSL2에선
az login
명령이 안된다. →az login --device-code
→https://microsoft.com/devicelogin
으로 접속해서 명령 결과로 나온 코드 입력하면 로긴된다.로그인 결과 [ { "cloudName": "AzureCloud", "id": "a573addd-xxxx-xxxx-xxxx-xxxxdataxxxx", "isDefault": true, "name": "무료 체험", "state": "Enabled", "tenantId": "4c6c5d14-xxxx-xxxx-xxxx-xxxxdataxxxx", "user": { "name": "wwdcr2@naver.com", "type": "user" } } ]
az account get-access-token
명령으로 토큰 확인root@jwjung:/web_infra# az account get-access-token { "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC80YzZjNWQxNC1kN2YyLTRjZjgtOWU0Zi0zY2MwYmNjMjlmNmIvIiwiaWF0IjoxNjEyMjU1NTE4LCJuYmYiOjE2MTIyNTU1MTgsImV4cCI6MTYxMjI1OTQxOCwiYWNyIjoiMSIsImFpbyI6IkFVUUF1LzhUQUFBQUo3c3JyaGhYdDFReWVkV05EYUJid0xZdWJwdytBMUlJTUo3NE55bDhvNU91Z0FXandjcjA1YnNlOTR2SGwxck5qM21tM3o2ajlUT3BSMTNEL0ZLeHdnPT0iLCJhbHRzZWNpZCI6IjE6bGl2ZS5jb206MDAwMzAwMDAwQ0JGNzI0NCIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIwNGIwNzc5NS04ZGRiLTQ2MWEtYmJlZS0wMmY5ZTFiZjdiNDYiLCJhcHBpZGFjciI6IjAiLCJlbWFpbCI6Ind3ZGNyMkBuYXZlci5jb20iLCJmYW1pbHlfbmFtZSI6Ikppd29uIiwiZ2l2ZW5fbmFtZSI6Ikp1bmciLCJncm91cHMiOlsiNjFmMGMxZTYtY2Q5ZS00MTdkLThlMGUtNzViOTIyMjg1N2E5Il0sImlkcCI6ImxpdmUuY29tIiwiaXBhZGRyIjoiMTIxLjEzMy4zNS4yMDQiLCJuYW1lIjoiSml3b25KdW5nIiwib2lkIjoiMWUxY2YwNDgtNTUxMi00MDNkLWJjYjItOTBhOWY0NDRmOTc5IiwicHVpZCI6IjEwMDMyMDAwRjM4RTQ4QTEiLCJyaCI6IjAuQUFBQUZGMXNUUExYLUV5ZVR6ekF2TUtmYTVWM3NBVGJqUnBHdS00Qy1lR19lMFp4QUxjLiIsInNjcCI6InVzZXJfaW1wZXJzb25hdGlvbiIsInN1YiI6ImFDak90eHE5MmN6ZnB3c29IQnlkbEtGTXllSGdKaG5XZjZabHFFXzdGYUUiLCJ0aWQiOiI0YzZjNWQxNC1kN2YyLTRjZjgtOWU0Zi0zY2MwYmNjMjlmNmIiLCJ1bmlxdWVfbmFtZSI6ImxpdmUuY29tI3d3ZGNyMkBuYXZlci5jb20iLCJ1dGkiOiJ1V29KeHB3Mm9VZVlya3RUemxBYUFBIiwidmVyIjoiMS4wIiwid2lkcyI6WyI2MmU5MDM5NC02OWY1LTQyMzctOTE5MC0wMTIxNzcxNDVlMTAiLCJiNzlmYmY0ZC0zZWY5LTQ2ODktODE0My03NmIxOTRlODU1MDkiXSwieG1zX3RjZHQiOjE2MDQ0MjExNDZ9.aoLFCYI0SInSMNiiYqWMs8xDwCySYyVBs0nrEaceaXSc8WICqeMmzAe_Kg_CS1Me3PQKaIzYphP08_kHgQj07sf4cVyO6mP4FJ9n10ft50prgQEOysEXtHZKBSeX-KlM3UEZtAh-EpVywLx7EUb9E0Qp3VJPHpuHiR7yhtv1sh_kwEIDAWsozvmVcXeMvB4wTPJgGBWsF-uqxlbsVLnsNFBgOBJq-yqweGMs9EvQL9BQS2ee1onCVDmE4IGtPsDXRlCBmtTMGvVx1Z-reEM_Vxk1P5Ig2r_D3zIX269scL6ffHOrThaza_dSMT5_LzN1n_WfASO1FKIMhJZkJiN8DA", "expiresOn": "2021-02-02 18:50:14.764144", "subscription": "a573addd-d0a0-4748-a03b-81c5b067d960", "tenant": "4c6c5d14-d7f2-4cf8-9e4f-3cc0bcc29f6b", "tokenType": "Bearer" }
- 아래 코드 실행
2.
terraform apply
결과 Error - 해결- apply 에러 내용 + Cloudflare를 통해 Azure만 접속되는 상황
AWS --- Error: Error associating EIP: Gateway.NotAttached: Network vpc-078cf7dd35449156f is not attached to any internet gateway status code: 400, request id: edab0fd5-9836-4082-9d1c-2476323bbc91 Error: error creating route table: InvalidVpcID.NotFound: The vpc ID 'aws_vpc.aws-vpc.id' does not exist status code: 400, request id: 53a2ff53-3c40-451a-9fc1-a78dc7647dd4 Error: error attaching EC2 Internet Gateway (igw-0cdd1a757913153fb): Error attaching internet gateway: InvalidVpcID.NotFound: The vpc ID 'aws_vpc.aws-vpc.id' does not exist status code: 400, request id: 2f8aa1dd-38f6-47c4-b8bd-2cd8f0970f51 GCP --- Error: Error creating Address: googleapi: Error 403: Compute Engine API has not been used in project 291777465078 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=291777465078 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry., accessNotConfigured Error: Error creating Network: googleapi: Error 403: Compute Engine API has not been used in project 291777465078 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=291777465078 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry., accessNotConfigured
- AWS :
aws_vpc.aws-vpc.id
변수값에 " " 빼주기 (변수를 문자로인식)
- GCP : 3번에서 해결
- apply 에러 내용 + Cloudflare를 통해 Azure만 접속되는 상황
4. GCP로 만든 인스턴스의 UserData가 입력되지 않는 문제 - 해결
- 생성된 인스턴스의 IP로 웹서버 접속불가
- SSH 접속을 허용하고 들어갔을 때 apache2가 설치되지 않음 = UserData 적용 안됨
gcp-main.tf
파일의 코드 변경#metadata_startup_script = data.template_file.metadata_startup_script.rendered # 이코드를 아래와 같이 변경 metadata = { startup-script = <<SCRIPT sudo apt-get update sudo apt update sudo apt install -y apache2 sudo systemctl start apache2 sudo systemctl enable apache2 echo "<h1> MultiCloud Demo Google Cloud </ h1>"| sudo tee /var/www/html/index.html SCRIPT }
4. 로드밸런싱 문제 - 해결
- 프로비저닝 완료 후 웹서버에 접속하면 1개의 서버에만 연결된다.
- 브라우저의 private모드, 기록삭제, 다른브라우저사용 등 다양한 시도를 해봤지만 1개의 서버에만 연결
- 하루종일 찾아보다가 오레곤에 생성한 인스턴스를 시작으로 핸드폰, 다른IP의 PC등 여러환경에서 시도해본 결과 로드밸런싱이 정상적으로 작동한다. 하지만 엔드디바이스의 접속정보를 가지고있는지 한서버에서는 한쪽으로만 라우팅이 되었다.
- 무료버전은 failover를 제공하지 않는다.
Terraform 환경
- 작업 디렉터리 : WSL2 내부의 /web_infra/.
- Terraform 버전 : v0.13.0 (0.14.5 버전은 실습 에러남) →
terraform 0.13upgrade .
명령으로 업그레이드
- Terraform 버전 변경 :
tfswitch
프로그램 사용
Cloudflare 가입 및 도메인 추가
1. Cloudflare 가입하기
- Cloudflare의 공식 홈페이지에서 무료 플랜 가입
- Cloudflare의 공식 홈페이지에서 무료 플랜 가입
4. Page Rule 설정을 통한 실제 페이지에 연결
- Cloudflare는 기본 3개의 Page Rules를 무료로 제공한다.
- 자동으로 cloudest.tistory.com 으로 Redirecting 되며 도메인 연결이 완료됐다.
AWS에 WEB배포 (Terraform)
1. 공통 변수에 대한 파일 생성 (
common-variables.tf
)common-variables.tf
파일에 아래 내용 추가#Define application name variable "app_name" { type = string description = "Application name" default = "kopicloud" } #Define application environment variable "app_environment" { type = string description = "Application environment" default = "demo" }
2. AWS 변수 선언 및 설정값 추가 (
aws-variables.tf
)aws-variables.tf
파일에 아래 내용 추가#AWS authentication variables variable "aws_access_key" { type = string description = "AWS Access Key" } variable "aws_secret_key" { type = string description = "AWS Secret Key" } variable "aws_key_pair" { type = string description = "AWS Key Pair" } #AWS Region variable "aws_region" { type = string description = "AWS Region for the VPC" default = "ap-northeast-2" } #AWS AZ variable "aws_az" { type = string description = "AWS AZ" default = "ap-northeast-2c" } #VPC CIDR variable "aws_vpc_cidr" { type = string description = "CIDR for the VPC" default = "10.1.0.0/16" } #Subnet CIDR variable "aws_subnet_cidr" { type = string description = "CIDR for the subnet" default = "10.1.1.0/24" }
3. AWS 인증정보 파일 생성 (
terraform.tfvars
)terraform.tfvars
파일에 아래 내용 추가#AWS authentication variables / 미리 생성한 액세스키, 비밀키, Key-pair이름 입력 aws_access_key = "[액세스키]" aws_secret_key = "[비밀키]" aws_key_pair = "[키페어 이름]" #SSH 접속을 하지 않기 때문에 생성한 Key-pair 이름만 알면 된다.
4. EC2에 Apache 설치 및
index.html
구성을 위한 파일 생성 (aws-user-data.sh
)- 이 작업은 부트스트랩 파일을 통한 작업이다.
aws-user-data.sh
파일에 아래 내용 추가#! /bin/bash sudo apt-get update sudo apt-get install -y apache2 sudo systemctl start apache2 sudo systemctl enable apache2 echo "<h1>MultiCloud Demo AWS</h1>" | sudo tee /var/www/html/index.html
5. VPC, 네트워크, EC2 및 보안그룹 구성 파일 생성 (
aws-main.tf
)aws-main.tf
파일 내부에 아래 내용 추가#Initialize the AWS Provider provider "aws" { access_key = var.aws_access_key secret_key = var.aws_secret_key region = var.aws_region } #Create the VPC resource "aws_vpc" "aws-vpc" { cidr_block = var.aws_vpc_cidr enable_dns_hostnames = true enable_dns_support = true tags = { Name = "${var.app_name}-${var.app_environment}-vpc" Environment = var.app_environment } } #Define the subnet resource "aws_subnet" "aws-subnet" { vpc_id = aws_vpc.aws-vpc.id cidr_block = var.aws_subnet_cidr availability_zone = var.aws_az tags = { Name = "${var.app_name}-${var.app_environment}-subnet" Environment = var.app_environment } } #Define the internet gateway resource "aws_internet_gateway" "aws-gw" { vpc_id = aws_vpc.aws-vpc.id tags = { Name = "${var.app_name}-${var.app_environment}-igw" Environment = var.app_environment } } #Define the route table to the internet resource "aws_route_table" "aws-route-table" { vpc_id = aws_vpc.aws-vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.aws-gw.id } tags = { Name = "${var.app_name}-${var.app_environment}-route-table" Environment = var.app_environment } } #Assign the public route table to the subnet resource "aws_route_table_association" "aws-route-table-association"{ subnet_id = aws_subnet.aws-subnet.id route_table_id = aws_route_table.aws-route-table.id } #Define the security group for HTTP web server resource "aws_security_group" "aws-web-sg" { name = "${var.app_name}-${var.app_environment}-web-sg" description = "Allow incoming HTTP connections" vpc_id = aws_vpc.aws-vpc.id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.app_name}-${var.app_environment}-web-sg" Environment = var.app_environment } } #Get latest Ubuntu 18.04 AMI data "aws_ami" "ubuntu-18_04" { most_recent = true owners = ["099720109477"] filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] } filter { name = "virtualization-type" values = ["hvm"] } } #Create Elastic IP for web server resource "aws_eip" "aws-web-eip" { vpc = true tags = { Name = "${var.app_name}-${var.app_environment}-elastic-ip" Environment = var.app_environment } } #Create EC2 Instances for Web Server resource "aws_instance" "aws-web-server" { ami = data.aws_ami.ubuntu-18_04.id instance_type = "t2.micro" subnet_id = aws_subnet.aws-subnet.id vpc_security_group_ids = [aws_security_group.aws-web-sg.id] associate_public_ip_address = true source_dest_check = false key_name = var.aws_key_pair user_data = file("aws-user-data.sh") tags = { Name = "${var.app_name}-${var.app_environment}-web-server" Environment = var.app_environment } } #Associate Elastic IP to Web Server resource "aws_eip_association" "aws-web-eip-association" { instance_id = aws_instance.aws-web-server.id allocation_id = aws_eip.aws-web-eip.id }
- AWS Terraform 배포 확인됨
Azure에 WEB배포 (Terraform)
1. Azure CLI 환경 구성
- 아래 코드 실행
apt update apt install azure-cli
- WSL2에선
az login
명령이 안된다. →az login --device-code
→https://microsoft.com/devicelogin
으로 접속해서 명령 결과로 나온 코드 입력하면 로긴된다.
az account get-access-token
명령으로 토큰 확인root@jwjung:/web_infra# az account get-access-token { "accessToken": "토큰 값", "expiresOn": "2021-02-02 18:50:14.764144", "subscription": "a573addd-d0a0-4748-a03b-81c5b067d960", "tenant": "테넌트 값", "tokenType": "Bearer" }
- 아래 코드 실행
2. Azure 변수 선언 및 설정값 추가 (
azure-variables.tf
)azure-variables.tf
파일에 아래 내용 추가#Location Resource Group variable "rg_location" { type = string description = "Location of Resource Group" default = "Korea Central" } #VNET CIDR variable "azure_vnet_cidr" { type = string description = "Vnet CIDR" default = "10.2.0.0/16" } #Subnet CIDR variable "azure_subnet_cidr" { type = string description = "Subnet CIDR" default = "10.2.1.0/24" } #Linux VM Admin User variable "linux_admin_user" { type = string description = "Linux VM Admin User" default = "tfadmin" } #Linux VM Admin Password variable "linux_admin_password" { type = string description = "Linux VM Admin Password" default = "S3cr3tP@ssw0rd" } #Linux VM Hostname variable "linux_vm_hostname" { type = string description = "Linux VM Hostname" default = "azwebserver1" } #Ubuntu Linux Publisher used to build VMs variable "ubuntu-linux-publisher" { type = string description = "Ubuntu Linux Publisher used to build VMs" default = "Canonical" } #Ubuntu Linux 18.x SKU used to build VMs variable "ubuntu-linux-18-sku" { type = string description = "Ubuntu Linux Server SKU used to build VMs" default = "18.04-LTS" }
3. VM에 Apache 설치 및
index.html
구성을 위한 파일 생성 (azure-user-data.sh
)azure-user-data.sh
파일에 아래 내용 추가#! /bin/bash sudo apt-get update sudo apt-get install -y apache2 sudo systemctl start apache2 sudo systemctl enable apache2 echo "<h1>MultiCloud Demo Azure</h1>" | sudo tee /var/www/html/index.html
4. Virtual Network, Azure 네트워크, VM 및 보안그룹 구성 (
azure-main.tf
)azure-main.tf
파일에 아래 내용 추가#Configure the Azure Provider provider "azurerm" { environment = "public" features {} } #Create Resource Group resource "azurerm_resource_group" "azure-rg" { name = "${var.app_name}-${var.app_environment}-rg" location = var.rg_location } #Create a virtual network resource "azurerm_virtual_network" "azure-vnet" { name = "${var.app_name}-${var.app_environment}-vnet" resource_group_name = azurerm_resource_group.azure-rg.name location = var.rg_location address_space = [var.azure_vnet_cidr] tags = { environment = var.app_environment } } #Create a subnet resource "azurerm_subnet" "azure-subnet" { name = "${var.app_name}-${var.app_environment}-subnet" resource_group_name = azurerm_resource_group.azure-rg.name virtual_network_name = azurerm_virtual_network.azure-vnet.name address_prefix = var.azure_subnet_cidr } #Create Security Group to access Web Server resource "azurerm_network_security_group" "azure-web-nsg" { name = "${var.app_name}-${var.app_environment}-web-nsg" location = azurerm_resource_group.azure-rg.location resource_group_name = azurerm_resource_group.azure-rg.name security_rule { name = "AllowHTTP" description = "Allow HTTP" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "Internet" destination_address_prefix = "*" } tags = { environment = var.app_environment } } #Associate the Web NSG with the subnet resource "azurerm_subnet_network_security_group_association" "azure-web-nsg-association" { subnet_id = azurerm_subnet.azure-subnet.id network_security_group_id = azurerm_network_security_group.azure-web-nsg.id } #Get a Static Public IP resource "azurerm_public_ip" "azure-web-ip" { name = "${var.app_name}-${var.app_environment}-web-ip" location = azurerm_resource_group.azure-rg.location resource_group_name = azurerm_resource_group.azure-rg.name allocation_method = "Static" tags = { environment = var.app_environment } } #Create Network Card for Web Server VM resource "azurerm_network_interface" "azure-web-nic" { name = "${var.app_name}-${var.app_environment}-web-nic" location = azurerm_resource_group.azure-rg.location resource_group_name = azurerm_resource_group.azure-rg.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.azure-subnet.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.azure-web-ip.id } tags = { environment = var.app_environment } } #Create web server vm resource "azurerm_virtual_machine" "azure-web-vm" { name = "${var.app_name}-${var.app_environment}-web-vm" location = azurerm_resource_group.azure-rg.location resource_group_name = azurerm_resource_group.azure-rg.name network_interface_ids = [azurerm_network_interface.azure-web-nic.id] vm_size = "Standard_B1s" delete_os_disk_on_termination = true delete_data_disks_on_termination = true storage_image_reference { publisher = var.ubuntu-linux-publisher offer = var.ubuntu-linux-offer sku = var.ubuntu-linux-18-sku version = "latest" } storage_os_disk { name = "${var.app_name}-${var.app_environment}-web-vm-os-disk" caching = "ReadWrite" create_option = "FromImage" managed_disk_type = "Standard_LRS" } os_profile { computer_name = var.linux_vm_hostname admin_username = var.linux_admin_user admin_password = var.linux_admin_password custom_data = file("azure-user-data.sh") } os_profile_linux_config { disable_password_authentication = false } tags = { environment = var.app_environment } } #Output output "azure-web-server-external-ip" { value = azurerm_public_ip.azure-web-ip.ip_address }
GCP에 WEB배포 (Terraform)
1. GCP 변수 선언 및 설정값 추가 (
gcp-variables.tf
)gcp-variables.tf
파일에 아래 내용 추가#GCP authentication file variable "gcp_auth_file" { type = string description = "GCP authentication file" } #Define GCP project name variable "gcp_project" { type = string description = "GCP project name" } #Define GCP region variable "gcp_region" { type = string description = "GCP region" default = "europe-west1" } #Define GCP zone variable "gcp_zone" { type = string description = "GCP zone" default = "europe-west1-b" } #Define subnet CIDR variable "gcp_subnet_cidr" { type = string description = "Subnet CIDR" default = "10.3.1.0/24" }
3. GCP 인증정보 파일 생성 (
terraform.tfvars
)terraform.tfvars
파일에 아래 내용 추가#GCP authentication variables gcp_project = "your-gcp-project" gcp_auth_file = "your-gcp-auth-file.json"
4. Compute Engine에 Apache 설치 및
index.html
구성을 위한 파일 생성 (gcp-user-data.sh
)gcp-user-data.sh
파일에 아래 내용 추가#! / bin / bash sudo apt-get update sudo apt update sudo apt install -y apache2 sudo systemctl start apache2 sudo systemctl enable apache2 echo "<h1> MultiCloud Demo Google Cloud </ h1>"| sudo tee /var/www/html/index.html
5. VPC, GCP 네트워크, Compute Engine 및 보안그룹 구성 (
gcp-main.tf
)gcp-main.tf
파일에 아래 내용 추가#Setup the GCP provider terraform { required_version = ">= 0.12" } provider "google" { project = var.gcp_project credentials = file(var.gcp_auth_file) region = var.gcp_region zone = var.gcp_zone } #Create VPC resource "google_compute_network" "gcp-vpc" { name = "${var.app_name}-${var.app_environment}-vpc" auto_create_subnetworks = "false" routing_mode = "GLOBAL" } #Create subnet resource "google_compute_subnetwork" "gcp-subnet" { name = "${var.app_name}-${var.app_environment}-subnet" ip_cidr_range = var.gcp_subnet_cidr network = google_compute_network.gcp-vpc.name region = var.gcp_region } #Firewall allow http resource "google_compute_firewall" "gcp-allow-http" { name = "${var.app_name}-${var.app_environment}-fw-allow-http" network = google_compute_network.gcp-vpc.name allow { protocol = "tcp" ports = ["80"] } target_tags = ["http"] } #Create a public ip for web server resource "google_compute_address" "gcp-web-ip" { name = "${var.app_name}-${var.app_environment}-web-ip" project = var.gcp_project region = var.gcp_region } #Define bootstrap file data "template_file" "metadata_startup_script" { template = file("gcp-user-data.sh") } #Create VM for web server resource "google_compute_instance" "gpc-web-server" { name = "${var.app_name}-${var.app_environment}-web-server" machine_type = "f1-micro" zone = var.gcp_zone tags = ["http"] boot_disk { initialize_params { image = "ubuntu-os-cloud/ubuntu-1804-lts" } } #metadata_startup_script = data.template_file.metadata_startup_script.rendered #부트 스트랩으로 넣는 방식이 인식이 안됨 metadata = { startup-script = <<SCRIPT sudo apt-get update sudo apt update sudo apt install -y apache2 sudo systemctl start apache2 sudo systemctl enable apache2 echo "<h1> MultiCloud Demo Google Cloud </ h1>"| sudo tee /var/www/html/index.html SCRIPT } network_interface { network = google_compute_network.gcp-vpc.name subnetwork = google_compute_subnetwork.gcp-subnet.name access_config { nat_ip = google_compute_address.gcp-web-ip.address } } } #Output output "external-ip-gcp-web-server" { value = google_compute_address.gcp-web-ip.address }
Cloudflare
1. Cloudflare 자격 증명 정보 추가 (
terraform.tfvars
)terraform.tfvars
파일에 아래 내용 추가#Cloudflare 인증 변수 cloudflare_email = "[이메일]" cloudflare_api_key = "[api 키]" cloudflare_zone_id = "[zone-id]"
2. Provider를 초기화하고 www 및 Root DNS 레코드를 생성 (
cloudflare-dns.tf
)cloudflare-dns.tf
파일에 아래 내용 추가#Define Cloudflare provider provider "cloudflare" { email = "메일" api_key = "API 키" } #Create www record for Amazon Web Services resource "cloudflare_record" "aws-www" { zone_id = "zone 아이디" name = "www" value = aws_eip.aws-web-eip.public_ip type = "A" proxied = true depends_on = [aws_eip.aws-web-eip] } #Create www record for Azure resource "cloudflare_record" "azure-www" { zone_id = "zone 아이디" name = "www" value = azurerm_public_ip.azure-web-ip.ip_address type = "A" proxied = true depends_on = [azurerm_public_ip.azure-web-ip] } #Create www record for Google Cloud resource "cloudflare_record" "gcp-www" { zone_id = "zone 아이디" name = "www" value = google_compute_address.gcp-web-ip.address type = "A" proxied = true depends_on = [google_compute_address.gcp-web-ip] } #Create root record for Amazon Web Services resource "cloudflare_record" "aws-root" { zone_id = "zone 아이디" name = "@" value = aws_eip.aws-web-eip.public_ip type = "A" proxied = true depends_on = [aws_eip.aws-web-eip] } #Create root record for Azure resource "cloudflare_record" "azure-root" { zone_id = "zone 아이디" name = "@" value = azurerm_public_ip.azure-web-ip.ip_address type = "A" proxied = true depends_on = [azurerm_public_ip.azure-web-ip] } #Create root record for Google Cloud resource "cloudflare_record" "gcp-root" { zone_id = "zone 아이디" name = "@" value = google_compute_address.gcp-web-ip.address type = "A" proxied = true depends_on = [google_compute_address.gcp-web-ip] } #Output AWS output "cloudflare-aws-www-record-id" { value = cloudflare_record.aws-www.id } output "cloudflare-aws-www-record-hostname" { value = cloudflare_record.aws-www.hostname } output "cloudflare-aws-root-record-id" { value = cloudflare_record.aws-root.id } output "cloudflare-aws-root-record-hostname" { value = cloudflare_record.aws-root.hostname } # Output Azure output "cloudflare-azure-www-record-id" { value = cloudflare_record.azure-www.id } output "cloudflare-azure-www-record-hostname" { value = cloudflare_record.azure-www.hostname } output "cloudflare-azure-root-record-id" { value = cloudflare_record.azure-root.id } output "cloudflare-azure-root-record-hostname" { value = cloudflare_record.azure-root.hostname } # Output GCP output "cloudflare-gcp-www-record-id" { value = cloudflare_record.gcp-www.id } output "cloudflare-gcp-www-record-hostname" { value = cloudflare_record.gcp-www.hostname } output "cloudflare-gcp-root-record-id" { value = cloudflare_record.gcp-root.id } output "cloudflare-gcp-root-record-hostname" { value = cloudflare_record.gcp-root.hostname }
실행 & 결과
terraform plan
으로 확인 후terraform apply
로 프로비저닝
결론
- AWS, Azure, GCP를 통해 웹서버 인스턴스의 멀티클라우드 실습을 성공적으로 마쳤다. 단순하게 서버의 인스턴스를 멀티클라우딩하여 가용성을 극대화하는 것을 넘어, 인프라와 플랫폼을 나누거나 플랫폼마다 제공하는 다양한 강력한 서비스를 섞어서 사용하는 것에 멀티클라우딩의 목적이 있을 것 같다.
- 또한 대부분의 기업의 최종 목표가 멀티클라우드 환경이라고는 하지만 모든 전략에 장단점이 있듯이 어려운 설계 및 관리를 비롯한 단점 또한 있을것이다.
Uploaded by Notion2Tistory v1.1.0