[Terraform] GCP 2티어 세부 구성

테라폼을 이용하여 GCP 2티어(워드프레스 + MySQL)을 구성하여 봤습니다.

2-tier 아키텍처

테라폼을 이용하여 인프라 구축하기위한 목표 아키텍쳐입니다.

GCP 테라폼 코드

변수 사용

로컬 변수

locals {
  project = "cloudexperience"
  env     = "wgpark"
  stage   = "dev"
  name    = "${local.project}-${local.env}-${local.stage}"
  region  = "asia-northeast3"
}

모듈 변수

module "wgparkTest" {
  source = "../00_structure"
  gcpSubnetPub = ["10.0.0.0/24","10.0.1.0/24"]
  gcpSubnetPri = ["10.0.2.0/24","10.0.3.0/24"]
  gcp-az = ["a","b"]
  gcp-sshkey ="dlsrk489"
}

제공자 설정

provider "google" {
  credentials = file("../../../keys/cloudexperience-58fb82c5a542.json")
  region      = local.region
  project     = local.project
}

Network 설정

resource "google_compute_network" "wgpark-vpc" {
  name                    = "${local.name}-vpc"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "wgpark-subnet-pub" {
  count         = length(var.gcpSubnetPub)
  name          = "${local.name}-subnetpub${count.index}"
  network       = google_compute_network.wgpark-vpc.name
  ip_cidr_range = var.gcpSubnetPub[count.index]
}

resource "google_compute_subnetwork" "wgpark-subnet-pri" {
  count         = length(var.gcpSubnetPri)
  name          = "${local.name}-subnetpri${count.index}"
  network       = google_compute_network.wgpark-vpc.name
  ip_cidr_range = var.gcpSubnetPri[count.index]
}

NAT 게이트웨이 & 라우트 경로 설정

resource "google_compute_router" "wgpark-router" {
  name    = "my-router"
  network = google_compute_network.wgpark-vpc.id
  region  = local.region
}

resource "google_compute_router_nat" "wgpark-nat" {
  name                               = "my-router-nat"
  router                             = google_compute_router.wgpark-router.name
  region                             = google_compute_router.wgpark-router.region
  nat_ip_allocate_option             = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"

}

방화벽 설정

resource "google_compute_firewall" "wgpark-firewall" {
  name    = "wgpark-firewall"
  network = google_compute_network.wgpark-vpc.name

  allow {
    protocol = "tcp"
    ports    = ["22"  ]
  }

  allow {
    protocol = "tcp"
    ports    = ["80", "8080"]
  }

  source_ranges = ["0.0.0.0/0"]
}

베스쳔호스트 인스턴스 생성

resource "google_compute_instance" "wgpark-bastioninstance" {
  name         = "${local.name}-bastion"
  machine_type = "e2-micro"
  zone         = "${local.region}-${var.gcp-az[0]}"

  tags = ["bastion"]

  network_interface {
    network    = google_compute_network.wgpark-vpc.id
    subnetwork = google_compute_subnetwork.wgpark-subnet-pub[0].id

    access_config {

    }
  }
  metadata = {
    ssh-keys = "${var.gcp-sshkey}:${file("../../../keys/tf-gcp-key.pub")}"
  }

  boot_disk {
    initialize_params {
      image = "centos-7-v20210916"
      size  = "20"
    }
  }
}

오토스케일링

인스턴스 템플릿 생성

resource "google_compute_instance_template" "wgpark-template-front" {
  name = "${local.name}-instancetemplate"

  tags = ["instancetemplate"]

  labels = {
    environment = "dev"
  }

  machine_type = "e2-small"

  disk {
    source_image = "centos-7-v20210916"
    auto_delete  = true
    boot         = true
  }

  network_interface {
    network    = google_compute_network.wgpark-vpc.id
    subnetwork = google_compute_subnetwork.wgpark-subnet-pub[0].id
  }

  metadata = {
    startup-script = file("../../../file/100_GCP.sh")
    ssh-keys = "${var.gcp-sshkey}:${file("../../../keys/tf-gcp-key.pub")}"
  }
# 생성 후 Data를 이용하여 ip를 가져와 설정해줄려 하였지만 데이터값을 start script에 넣지못해 주석처리하였습니다.
#  depends_on = [
#    google_sql_database_instance.wgaprk-mysql
#  ]
  #  require
  #  dick,machine_type,networkinterface
  #
}

인스턴스에 들어갈 start script

#! /bin/bash
sudo su -
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

yum install -y httpd wget

yum -y install epel-release
yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum install -y yum-utils
yum-config-manager --enable remi-php72
yum install -y php php-cli php-mysql

wget https://ko.wordpress.org/latest-ko_KR.tar.gz
tar -xzf latest-ko_KR.tar.gz
cp -a wordpress/* /var/www/html/
cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php

chown apache.apache /var/www/html/*

sed -i 's/DirectoryIndex index.html/DirectoryIndex index.php/g' /etc/httpd/conf/httpd.conf
systemctl start httpd
systemctl enable httpd
echo "hi" >> /var/www/html/check.html
sed -i 's/database_name_here/wordpress/g' /var/www/html/wp-config.php
sed -i 's/username_here/wordpress/g' /var/www/html/wp-config.php
sed -i 's/password_here/It12345!/g' /var/www/html/wp-config.php
sed -i 's/localhost/ipaddress/g' /var/www/html/wp-config.php

sed -i "/define( 'AUTH_KEY'/d" /var/www/html/wp-config.php
sed -i "/define( 'SECURE_AUTH_KEY'/d" /var/www/html/wp-config.php
sed -i "/define( 'LOGGED_IN_KEY'/d" /var/www/html/wp-config.php
sed -i "/define( 'NONCE_KEY'/d" /var/www/html/wp-config.php
sed -i "/define( 'AUTH_SALT'/d" /var/www/html/wp-config.php
sed -i "/define( 'SECURE_AUTH_SALT'/d" /var/www/html/wp-config.php
sed -i "/define( 'LOGGED_IN_SALT'/d" /var/www/html/wp-config.php
sed -i "/define( 'NONCE_SALT'/d" /var/www/html/wp-config.php



sed -i '51 i\define("AUTH_KEY",         "3{t^k2=S@d0-qwq)YIlQIswF$slz{rrduN%1 Le06yhg:-f.v%%g|e8;lb#%U8-F");' /var/www/html/wp-config.php
sed -i '52 i\define("SECURE_AUTH_KEY",  "^`,v|v)+8oQ`%){b4f2t$:%;yLE[y]K,0wlqQt5mUKvds:v^6GA$%SCqX3P>f `&");' /var/www/html/wp-config.php
sed -i '53 i\define("LOGGED_IN_KEY",    "oh9-seEDDS`Mo-g-{~/C*^v|GX4!_|BU^F,bfKfiIBe IY.RH+,MmaQ{@PwI,3y+");' /var/www/html/wp-config.php
sed -i '54 i\define("NONCE_KEY",        "4-##^p.hqXBw6.FdP-{s-2eY{Ra~[ta[L-?B-/p<uzvb0 za_P]@3Gp`5,pw,l]T");' /var/www/html/wp-config.php
sed -i '55 i\define("AUTH_SALT",        "FC=xS:x+/?M])4Kjt~m*7ys[J92CwQ&Sv9SP[7_zm~P|pXE%q:CD#NqjULl5D?@J");' /var/www/html/wp-config.php
sed -i '56 i\define("SECURE_AUTH_SALT", "?`(ATb,+(X|P/G(O`/bweK+}iX9^1v6@Q2g:zm30#umb[$X?9kne9rK~c #(N=5~");' /var/www/html/wp-config.php
sed -i '57 i\define("LOGGED_IN_SALT",   ";R[pT6C<eiZ}zaH-&=)OW6bnCn0m&6h@gMg8gR&ju25Z,+h?|[C)1>8rb?E>V1+S");' /var/www/html/wp-config.php
sed -i '58 i\define("NONCE_SALT",       "a/ h~L(vW>cx-2kP<qV+&$62`g45aAW<5MHkk!bbgX@49vh(6s|uq!M$<_Y{c^%{");' /var/www/html/wp-config.php


인스턴스 그룹 관리 설정

resource "google_compute_instance_group_manager" "wgpark-instance-group" {
  # require
  # base_insatance_name ,version ,name, zone
  name = "${local.name}-igm"

  base_instance_name = "wgpark-autoscaling"

  target_size  = 2
  # zone을 리전별로할려면 사용할 모든 가용존을 주면됨.
  #  zone = ["${local.region}${var.gcp-az[0]}","${local.region}${var.gcp-az[1]}"]
  zone         = "asia-northeast3-a"
  version {
    instance_template = google_compute_instance_template.wgpark-template-front.id
  }


  named_port {
    name = "http"
    port = "80"
  }

  auto_healing_policies {
    health_check      = google_compute_health_check.wgpark-autohealing.id
    initial_delay_sec = 10
  }
  depends_on = [
    google_compute_router_nat.wgpark-nat
  ]
}

인스턴스 그룹 헬스 체크

resource "google_compute_health_check" "wgpark-autohealing" {
  name                = "autohealing-health-check"
  check_interval_sec  = 5
  timeout_sec         = 5
  healthy_threshold   = 2
  unhealthy_threshold = 10 # 50 seconds

  http_health_check {
    request_path = "/"
    port         = "80"
  }
}

로드밸런서

로드밸런서 외부 아이피 할당

resource "google_compute_global_address" "wgpark-pubip" {
  name = "${local.name}-pubip"
}

프론트엔드 생성

resource "google_compute_global_forwarding_rule" "wgpark-fr" {
  name                  = "${local.name}-fr"
  ip_protocol           = "HTTP"
  load_balancing_scheme = "EXTERNAL"
  port_range            = "80"
  target                = google_compute_target_http_proxy.wgpark-tghttpproxy.id
  ip_address            = google_compute_global_address.wgpark-pubip.id
}

resource "google_compute_target_http_proxy" "wgpark-tghttpproxy" {
  name    = "${local.name}-tg-httpproxy"
  url_map = google_compute_url_map.wgpark-urlmap.id
}

프론트와 백엔드서비스 매핑

resource "google_compute_url_map" "wgpark-urlmap" {
  name            = "${local.name}-map"
  default_service = google_compute_backend_service.wgpar-backend.id
}

백엔드 서비스 생성

resource "google_compute_backend_service" "wgpar-backend" {
  name                  = "${local.name}-backend-service"
  protocol              = "HTTP"
  port_name             = "test"
  load_balancing_scheme = "EXTERNAL"
  timeout_sec           = 10
  enable_cdn            = false
  health_checks         = [google_compute_health_check.wgpark-httplb-health.id]
  backend {
    group           = google_compute_instance_group_manager.wgpark-instance-group.instance_group
    capacity_scaler = 1.0
  }
}

백엔드 서비스 헬스체크

#로드밸런서 상태확인
resource "google_compute_health_check" "wgpark-httplb-health" {

  name                = "${local.name}-loadhealth"
  check_interval_sec  = 5
  timeout_sec         = 5
  healthy_threshold   = 2
  unhealthy_threshold = 10 # 50 seconds

  http_health_check {
    request_path = "/check.html"
    port         = "80"
  }
}

Cloud SQL

DB 인스턴스 네트워크 생성

resource "google_compute_global_address" "wgpark-private-ip-address" {


  name          = "db"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  address = "10.0.4.0"
  prefix_length = 24
  network       = google_compute_network.wgpark-vpc.id
}
resource "google_service_networking_connection" "wgparkprivate-vpc-connection" {


  network                 = google_compute_network.wgpark-vpc.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.wgpark-private-ip-address.name]
}

sql DB 생성

resource "google_sql_database" "wgpark-database" {
  name     = "my-database"
  instance = google_sql_database_instance.wgaprk-mysql.name
}
resource "google_sql_database_instance" "wgaprk-mysql" {
  name             = "${local.name}-mysql"
  database_version = "MYSQL_5_7"
  region           = local.region

  settings {
    tier = "db-f1-micro"
    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.wgpark-vpc.id
    }
  }
  depends_on = [
    google_service_networking_connection.wgparkprivate-vpc-connection
  ]
}

DB 유저 및 스키마 생성

resource "google_sql_user" "users" {
  name     = "wordpress"
  instance = google_sql_database_instance.wgaprk-mysql.name
  password = "It12345!"
}
resource "google_sql_database" "database" {
  name     = "wordpress"
  instance = google_sql_database_instance.wgaprk-mysql.name
}

좋은 웹페이지 즐겨찾기