본문 바로가기

KOSA 클라우드 솔루션즈 아키텍트 양성과정

[7.5] AZURE CLI / GCP CLI / Terraform(AZURE, GCP), Ansible

azure-terraform

 

# git clone https://github.com/hali-linux/azure_set.git

=> tf 파일들 모아 놓은 저장소
# vi variables.tf

variable "resource_group_name_prefix" {
  default       = "rg"
  description   = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
}

variable "resource_group_location" {
  default = "koreacentral"
  description   = "Location of the resource group."
}

 

 

# vi main.tf


provider "azurerm" {
  features {}
}

resource "random_pet" "rg-name" {
  prefix    = var.resource_group_name_prefix
}

resource "azurerm_resource_group" "rg" {
  name      = random_pet.rg-name.id
  location  = var.resource_group_location
}

# Create virtual network
resource "azurerm_virtual_network" "myterraformnetwork" {
  name                = "myVnet"
  address_space       = ["10.113.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

# Create subnet
resource "azurerm_subnet" "myterraformsubnet" {
  name                 = "mySubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
  address_prefixes     = ["10.233.0.0/24"]
}

# Create public IPs
resource "azurerm_public_ip" "myterraformpublicip" {
  name                = "myPublicIP"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  allocation_method   = "Dynamic"       => 동적으로 IP 부여
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "myterraformnsg" {
  name                = "myNetworkSecurityGroup"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"    => 출발지 포트는 모든 포트 허용
    destination_port_range     = "22"
    source_address_prefix      = "112.221.225.165/32"
    destination_address_prefix = "*"
  }
  security_rule {
    name                       = "HTTP"
    priority                   = 1002
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# Create network interface
resource "azurerm_network_interface" "myterraformnic" {
  name                = "myNIC"
=> 자원을 만든 후 리스트 내에서 불리는 이름
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "myNicConfiguration"
    subnet_id                     = azurerm_subnet.myterraformsubnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.myterraformpublicip.id
  }  => 랜카드에 프라이빗과 퍼블릭 IP 할당
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
=> NIC와 보안 그룹을 연결
  network_interface_id      = azurerm_network_interface.myterraformnic.id
  network_security_group_id = azurerm_network_security_group.myterraformnsg.id
}

# Create (and display) an SSH key
resource "tls_private_key" "example_ssh" {
=> tls(Transfet layer security) : 암호화 키를 만드는 tls프로토콜을 이용해 키 페어를 생성
  algorithm = "RSA"
  rsa_bits  = 4096
}

# Create virtual machine
resource "azurerm_linux_virtual_machine" "myterraformvm" {
  name                  = "myVM"
  location              = azurerm_resource_group.rg.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.myterraformnic.id]
  size                  = "Standard_B1s"

  os_disk {
    name                 = "myOsDisk"
    caching              = "ReadWrite"
    storage_account_type = "Premium_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
=> Ubuntu를 만든 회사의 사명을 기입
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  computer_name                   = "myvm"
=> 호스트 네임
  admin_username                  = "azureuser"
  custom_data                     = filebase64("httpd-azure.txt")
=> base64 : 디코드 과정에서 파일이 깨지는 것을 방지
  disable_password_authentication = true

  admin_ssh_key {
    username   = "azureuser"
    public_key = tls_private_key.example_ssh.public_key_openssh
  }

}

# vi outputs.tf

output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}

output "public_ip_address" {
  value = azurerm_linux_virtual_machine.myterraformvm.public_ip_address
}

output "tls_private_key" {
  value     = tls_private_key.example_ssh.private_key_pem
  sensitive = true
}

# terraform init
# terraform plan
# terraform apply
# terraform output -raw tls_private_key > azure-key.pem
프라이빗 키를 pem키로 생성하겠다는 표준 출력
# terraform output public_ip_address
# chmod 400 azure-key.pem
# ssh -i azure-key.pem azureuser@<public_ip_address>

 

terraform init

- tls와 random은 플러그인

- azurerm은 provider


GCP CLI

# mkdir gcp_cli && cd $_
# tee -a /etc/yum.repos.d/google-cloud-sdk.repo << EOM
=> EOM : End Of Message
=> 최신 버전의 패키지를 내려 받기 위해서는 저장소를 지정해줘야 함
=> tee : google-cloud-sdk.repo 라는 파일을 만들어 주면서 <<(표준 입력)을 통해 하단의 내용을 넣어주는 명령어
[google-cloud-cli]
name=Google Cloud CLI
baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el8-x86_64
=> 최신 버전의 gcloud 도구가 어느 경로에 있는지 정의
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOM
# yum install -y google-cloud-cli
# gcloud --version
# gcloud init --console-only
asia-northeast3-a
# gcloud compute networks create new-vpc --subnet-mode=custom
=> --subnet-mode=custom 해주지 않으면 모든 리전에 vpc가 생성됨
# gcloud compute networks subnets create new-subnet --network=new-vpc --range=192.168.0.0/16 --region=asia-northeast3
# gcloud compute firewall-rules list
# gcloud compute firewall-rules create new-vpc-allow-ssh --allow=tcp:22 --description="Allow incoming traffic on TCP port 22" --direction=INGRESS --network=new-vpc --source-ranges 112.221.225.165/32
# gcloud compute firewall-rules create new-vpc-allow-http --allow=tcp:80 --description="Allow incoming traffic on TCP port 80" --direction=INGRESS --network=new-vpc --source-ranges 0.0.0.0/0
# gcloud compute images list
# gcloud compute images describe centos-7-v20220621 \
    --project=centos-cloud
# gcloud compute machine-types list --filter="zone:( asia-northeast3-a )"
# vi httpd-gcp.txt
#!/bin/bash
yum install -y httpd
systemctl enable --now httpd
echo "Hello GCP CLI" > /var/www/html/index.html

# gcloud compute instances create web01 \
    --image=centos-7-v20220621 \
    --image-project=centos-cloud \
    --machine-type=e2-micro \
    --network=new-vpc \
    --subnet=new-subnet \
    --tags http-server,https-server \
    --zone=asia-northeast3-a \
    --metadata-from-file=startup-script=httpd-gcp.txt

메타 데이터에 키를 넣어줘야 함


# ssh-keygen -t rsa -f /root/.ssh/johnlee -C johnlee -b 2048
=> 2048 : 암호화 비트수 => 커지면 커질 수록 암호가 복잡해짐
=> rsa방식의 키 페어를 생성
# vi /root/.ssh/johnlee.pub
johnlee:ssh-rsa

ssh-rsa 앞에 키 이름을 넣어줘야 함


# gcloud compute os-login ssh-keys add \
    --key-file=/root/.ssh/johnlee.pub \
    --project=gcp-johnlee2022-352701 \
    --ttl=365d
=> 키의 유효기간(Time To Live)을 365일을 두고, 업로드 시키는 과정
# gcloud compute instances add-metadata web01 --metadata-from-file ssh-keys=/root/.ssh/johnlee.pub
=> web01이라는 이름의 vm의 메타데이터에 키를 등록하는 과정
# gcloud compute instances describe web01
# curl 34.64.150.44
# ssh -i /root/.ssh/johnlee johnlee@34.64.150.44
# gcloud compute instances delete web01
# gcloud compute firewall-rules list
# gcloud compute firewall-rules delete new-vpc-allow-http
# gcloud compute firewall-rules delete new-vpc-allow-ssh
# gcloud compute networks subnets delete new-subnet
# gcloud compute networks delete new-vpc

credentials.json 생성하기

 

GCP 콘솔 서비스 계정

 

계정 이름 : Terraform-access, 엑세스 권한 : 소유자 설정 후 완료 클릭

 

새 키 만들기
JSON 유형의 키 만들기, 이후 윈도우 다운로드 폴더에서 키 파일 이름을 credentials.json으로 변경

 

/root/gcp-set에 credentials.json 업로드


gcp_terraform

# git clone https://github.com/hali-linux/gcp_set.git
vi provider.tf

provider "google" {
  credentials = file("credentials.json")  => credentials 파일을 통해 자격증명
  project = "gcp-gcp-skk0705"  => 프로젝트의 ID를 가져옴
  region = "asia-northeast3"
  zone = "asia-northeast3-a"
}

# vi main.tf

resource "google_compute_network" "custom-test" {
  name                    = "new-vpc"
  auto_create_subnetworks = false => auto로 만들 것이 아니므로 false
}

resource "google_compute_firewall" "http-server" {
  name    = "default-allow-http-terraform"
  network = "new-vpc"

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

  // Allow traffic from everywhere to instances with an http-server tag
  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["http-server"]
}

resource "google_compute_firewall" "ssh-server"
{ name = "default-allow-ssh-terraform"
network = "new-vpc"

  allow {
    protocol = "tcp" ports = ["22"]
}
  source_ranges = ["0.0.0.0/0"]
  target_tags = ["ssh-server"]
}

resource "google_compute_subnetwork" "network-with-private-ip-ranges" {
   name          = "new-subnet"
   ip_cidr_range = "192.168.0.0/16" 
   region        = "asia-northeast3"
   network       = google_compute_network.custom-test.id
}

resource "google_compute_instance" "default" {
  name         = "vm-from-terraform"
  machine_type = "e2-micro"
  zone         = "asia-northeast3-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }  => 이미지를 선택하는 항목, GCP에서는 debian이 디폴트

  network_interface {
    network = google_compute_network.custom-test.name
    subnetwork = google_compute_subnetwork.network-with-private-ip-ranges.name

    access_config {
      // Include this section to give the VM an external ip address
    }
  }

    metadata_startup_script = file("/root/gcp_set/script.txt")
=> 절대 경로로 쓰지 않으면 인식 하지 못함
    // Apply the firewall rule to allow external IPs to access this instance
    tags = ["http-server"]
}

# vi output.tf

output "ip" {
  value = "${google_compute_instance.default.network_interface.0.access_config.0.nat_ip}"
}
# terraform init
# terraform plan
# terraform apply
# terraform output ip

 


Known host 애러

known host : 이 서버가 믿을 수 있는 서버인지 기록해 놓음
known host를 지웠다가 다시 ssh 접근 하면 됨


Ansible

 

 

스페이스바 눌러야 체크됨
ssh접속 후, sudo vi /etc/ssh/sshd_config
루트 계정으로 우분투에 접속할 수 있도록 셋팅(ansible은 ssh 접근이 필요)

 

루트 계정으로 접속해서 비밀번호 설정 후 다시 일반 사용자로 가서 sudo systemctl restart sshd

 

루트 계정으로 로그인 완료

- 이후 poweroff 시켜주고 virtualBox 매니져에서 가상 시스템 내보내기 실행