본문 바로가기
Tech/Terraform

[T101_3기] 1주차 - Terraform 설명 및 환경 구성 (1/2) - 설명 및 구성

by 구름_쟁이 2023. 9. 1.

본 시리즈는 가시다님의 T101(테라폼으로 시작하는 IaC) 3기 진행 내용입니다. (가시다님 노션)

 

도서 정보

https://www.yes24.com/Product/Goods/119179333

 

테라폼으로 시작하는 IaC - 예스24

“현업에서 요구하는 진짜 IaC 사용법”테라폼으로 배우는 인프라 운영의 모든 것IaC는 효율적인 데브옵스와 클라우드 자동화 구축을 위해 꼭 필요한 기술로 각광받고 있다. 그중에서도 테라폼

www.yes24.com

실습 코드

https://github.com/terraform101

 

목차

1. Terraform 설명 및 환경 구성
2. 도전 과제

 

 


1-1. Terraform 설명

테라폼 : 하시코프사에서 공개한 IaC 도구

 

‘하시코프의 철학 - 링크’ 중 3가지를 담아서 테라폼을 설계 : 워크플로우에 집중, 코드형 인프라, 실용주의

 

테라폼 제공 유형 : 3가지 유형

  1. On-premise : Terraform이라 불리는 형태로, 사용자의 컴퓨팅 환경에 오픈소스 바이너리툴인 테라폼을 통해 사용
  2. Hosted SaaS : Terraform Cloud로 불리는 SaaS로 제공되는 구성 환경으로 하시코프가 관리하는 서버 환경이 제공
  3. Private Install : Terraform Enterprise로 불리는 서버 설치형 구성 환경으로, 기업의 사내 정책에 따라 프로비저닝 관리가 외부 네트워크와 격리 - 링크

 

 

테라폼 클라우드 가격정책 - [참고: Pricing, Feature]

  • Free : 리소스 500개 까지 무료 → 커뮤니티 버전
  • Standard : Free + 워크플로우 기능 추가 + 동시실행(Concurrency 개수 3개)
  • Plus : 정책, 보안, 신뢰성, 확장성 등 기업형 고객에게 적합(대규모 사용자를 위한 비용모델)
  • Enterprise : Plus와 대부분 유사하며 설치형 모델

 

 

 

결론

Terraform Cloud 을 사용해도 괜찮다~ (매달 500개 리소스까지)

회사 제품에 도입하는 경우 BSL도 잘 읽어보고...사용하자

 


 

1-2. 환경 구성

실습에 앞서 AWS Free-Tier와 IAM User 생성이 필요.

 

Mac도 있지만 윈도우에서 WSL 설치 후 해당 리눅스 환경을 준비해서 진행하도록 한다.

(VS Code 설치 - Extension(WSL) 설치 후 WSL 환경을 VS Code로 띄웠다)

 

terraform 설치 및 자동완성

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

# 테라폼 버전 정보 확인
terraform version


# 테라폼 자동 완성
terraform -install-autocomplete

cat ~/.bashrc |tail -n 2
source ~/.bashrc

차이점 확인
terraform <Tab>

terraform 자동완성 차이점

설치 전

설치 후

 

 

tfenv 설치

git clone https://github.com/tfutils/tfenv.git ~/.tfenv
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile

tfenv list-remote

sudo apt-get install unzip
# CentOS라면 sudo yum install unzip


tfenv install 1.5.6

## 결과
Installing Terraform v1.5.6
Downloading release tarball from https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_linux_amd64.zip
############################################################################################################ 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.5.6/terraform_1.5.6_SHA256SUMS
Not instructed to use Local PGP (/home/hw038/.tfenv/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
Archive:  /tmp/tfenv_download.FdLKhP/terraform_1.5.6_linux_amd64.zip
  inflating: /home/hw038/.tfenv/versions/1.5.6/terraform  
Installation of terraform v1.5.6 successful. To make this your default version, run 'tfenv use 1.5.6'


tfenv use 1.5.6

 

 

aws cli 설치

sudo apt install awscli

aws --version

 

 

aws cli 동작 확인

aws s3 ls

저는 이미 aws credential을 설정해두어서 관련 정보가 다 나오는군요.

aws credential 설정 방법

aws configure
... >> 입력

aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************DYFF shared-credentials-file
secret_key     ****************m7Za shared-credentials-file
    region           ap-northeast-2      config-file    ~/.aws/config

# 방안2. 환경 변수로 자격증명 설정
Linux or macOS
export AWS_ACCESS_KEY_ID=AKIAIOS******
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI********
export AWS_DEFAULT_REGION=ap-northeast-2

 

실습에 필요한 툴(watch, jq, tree) 설치

sudo apt install jq tree watch -y

 

default VPC 존재 확인

난 없다... 어디 놔두고 왔다보다.(생성하자)

# default VPC를 생성
aws ec2 create-default-vpc

# default Subnet 생성
aws ec2 create-default-subnet --availability-zone ap-northeast-2a
aws ec2 create-default-subnet --availability-zone ap-northeast-2b
aws ec2 create-default-subnet --availability-zone ap-northeast-2c
aws ec2 create-default-subnet --availability-zone ap-northeast-2d

# (참고)default VPC 없을경우 발생하는 에러
Plan: 1 to add, 0 to change, 0 to destroy.
aws_instance.example: Creating...
╷
│ Error: creating EC2 Instance: MissingInput: No subnets found for the default VPC 'vpc-0b6b2b612ffb62e0b'. Please specify a subnet.
│       status code: 400, request id: e4723b72-7f61-4b3b-b5b1-32f0501ff617
│ 
│   with aws_instance.example,
│   on main.tf line 5, in resource "aws_instance" "example":
│    5: resource "aws_instance" "example" {
│

잘 생성된 것 확인

 

 

이제 배포할 vm에서 쓸 이미지는 어떤 것이 있는지 확인해보자

(너무 많이 나오니까 마지막 10개만 확인)

#aws ec2 describe-images --owners self amazon
aws ec2 describe-images --owners self amazon --query 'Images[*].[ImageId]' --output text | tail -n 10

aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query "Parameters[].Name"
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query "Parameters[].Value"

 

EC2 1대 배포 실행

예제 tf 파일 생성

# VS Code 터미널2
cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-084e92d3e117f7692"
  instance_type = "t2.micro"
}
EOT

 

배포 실행

# 초기화
terraform init
ls -al
tree .terraform

# plan 확인
terraform plan

# apply 실행
terraform apply
 Enter a value: yes 입력

# ec2 생성 확인 : aws 웹 관리 콘솔에서도 확인 - 서울 리전 선택
export AWS_PAGER=""
aws ec2 describe-instances --output table

 

배포 결과

main.tf에 값을 추가 후 재배포

cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-084e92d3e117f7692"
  instance_type = "t2.micro"

  tags = {
    Name = "t101-study"
  }

}
EOT

(tags를 추가함)

 

# plan 실행 시 아래와 같은 정보가 출력
terraform plan
# aws_instance.example will be updated in-place
  ~ resource "aws_instance" "example" {
        id                                   = "i-01f08fdf499c346dc"
      ~ tags                                 = {
          + "Name" = "t101-study - NetCloudy"
        }
      ~ tags_all                             = {
          + "Name" = "t101-study - NetCloudy"
        }
        # (30 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

# apply 실행
terraform apply
 Enter a value: yes 입력

# 모니터링 : [터미널1]에 Name 확인

tag가 추가된 것 확인

 

 

EC2 삭제

# 리소스 삭제
terraform destroy
 Enter a value: yes 입력

혹은
terraform destroy -auto-approve

 

 

좀더 실용적인(?) 배포를 해보자

Ubuntu 에 웹 서비스를 하도록 배포.

# 각자 편한 디렉터리를 생성해주시면 됩니다
cd ..
mkdir t101-1week-web
cd t101-1week-web
  • 코드 파일 작성 : user_data 에 실행 명령어 작성
cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami                    = "ami-0c9c942bd7bf113a2"
  instance_type          = "t2.micro"

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, T101 Study" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags = {
    Name = "terraform-Study-101"
  }
}
EOT
  • 배포 실행
# init
terraform init

# plan
terraform plan
 + user_data                            = "d91ca31904077f0b641b5dd5a783401396ffbf3f"
# apply 실행
terraform apply -auto-approve
  • 웹 서버 접속 시도 : 터미널3에서 실행
# [터미널3] 변수 지정
PIP=<각자 자신의 EC2 Public IP>
PIP=54.180.29.38
while true; do curl --connect-timeout 1  http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done

접속 결과

hw038@HH_HOME:~/t101$ while true; do curl --connect-timeout 1  http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done
curl: (3) URL using bad/illegal format or missing URL
------------------------------
Fri Sep  1 23:01:21 KST 2023
curl: (3) URL using bad/illegal format or missing URL
------------------------------

안되는 이유는?

더보기

정답은

SG 설정을 해주지 않았기 때문.!

 

아래 코드 블럭을 사용하면 된다.

cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami                    = "ami-0c9c942bd7bf113a2"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, T101 Study" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags = {
    Name = "Single-WebSrv"
  }
}

resource "aws_security_group" "instance" {
  name = var.security_group_name

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}
EOT

 

 

다이어그램으로 보는 방법

# (옵션) 리소스 생성 그래프 확인
terraform graph

# graph 확인 > 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

 

 

결론

기본적인 테라폼 사용법을 익혔다!

다음은 도전 과제를 진행해보자!

댓글