728x90
반응형
안녕하세요! 늑대양입니다!!
이번에는 페이지 분량을 생각하여 내용을 분할, 2.4장 과 2.5장 내용을 담았습니다 🤓
2.4 단일 웹 서버 배포
- 목표: 배포한 인스턴스에 웹 서버 실행
- "Hello, World" 출력
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p 8080 &
# 해당 배시 스크립트는 "Hello, World" 텍스트를 index.html 파일에 저장 후,
# busybox를 통해 8080 포트에서 웹서버를 실행하여 제공합니다
# busybox 명령어를 nohub 과 & 로 매핑하여,
# 배시 스크립트가 종료되더라도 웹 서버가 백그라운드에서 영구적으로 실행되도록 합니다.
- HTTP 기본 포트인 80이 아닌 8080을 사용하는 이유는 Well-Known 포트 (~1023)를 Listen 하려면 Root 사용자 권한이 필요하기 때문입니다.
resource "aws_instance" "server" {
ami = "ami-0ba5cd124d7a79612" # Ubuntu Server 18.04 LTS
instance_type = "t3.micro" # type도 다시 t3.micro로 변경
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags = {
Name = "TEST-WEB"
}
}
- <<-EOF 와 EOF는 테라폼의 heredoc 구문으로 이를 이용해 줄 바꿈 문자 없이 여러 줄로 된 코드 입력이 가능합니다.
resource "aws_security_group" "instance" {
name = "TEST-WEB-instance"
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
- 이제 서버에 연결해줄 보안그룹도 생성 및 설정을 진행합니다.
- 보안 그룹의 ID를 aws_instance 리소스의 vpc-security_group_ids 인수에 저장하는 과정 진행이 필요합니다만..
- 그전에 테라폼의 표현식을 먼저 학습하도록 합니다 🙏
값을 반환하는 것이라면 무엇이든지 테라폼의 표현식입니다.
- ami = "ami-0ba5cd124d7a79612" 와 같은 문자열 및 숫자처럼 간단한 문자열 표현식은 이미 체득 완료!
- 이 중에서 참조(reference)는 특히 유용한 표현 중 하나!
- 코드의 다른 부분에서 값에 액세스할 수 있게 해주는 표현식!!
# main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "server" {
ami = "ami-0ba5cd124d7a79612"
instance_type = "t3.micro"
vpc_security_group_ids = **[aws_security_group.instance.id]**
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p 8080 &
EOF
tags = {
Name = "TEST-WEB"
}
}
resource "aws_security_group" "instance" {
name = "TEST-WEB-sg"
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# aws_security_group 리소스의 경우,(main.tf가 아닌)다른 파일로 빼서 작성하는 것이 좋아 보입니다.
- 하나의 리소스에서 다른 리소스로 참조를 추가하면 내재된 종속성이 작성됩니다.
종속성 구문 분석 → 종속성 그래프 작성 → 리소스를 생성하는 순서를 자동으로 결정
- 쉽게 말해 "참조해올 것이 있다면 그것부터 만든다"고 생각하시면 좋습니다.
- 테라폼은 종속성 그래프(트리)를 따라갈 때, 가능한 한 많은 리소스를 병렬로 생성 → 효율적 적용
$ tf apply # terraform 명령어에 대한 alias로 tf를 추천드립니다
...
Plan: 2 to add, 0 to change, 1 to destroy.
...
Enter a Value: yes
...
aws_instance.server: Destroying... [id=i-01c97181ff54097e1]
aws_instance.server: Still destroying... [id=i-01c97181ff54097e1, 10s elapsed]
aws_instance.server: Still destroying... [id=i-01c97181ff54097e1, 20s elapsed]
aws_instance.server: Still destroying... [id=i-01c97181ff54097e1, 30s elapsed]
aws_instance.server: Still destroying... [id=i-01c97181ff54097e1, 40s elapsed]
aws_instance.server: Destruction complete after 40s
aws_security_group.instance: Creating...
aws_security_group.instance: Creation complete after 2s [id=sg-00859bbb37fb1f398]
aws_instance.server: Creating...
aws_instance.server: Still creating... [10s elapsed]
aws_instance.server: Creation complete after 12s [id=i-054f1344a35d7ae8b]
**Apply complete! Resources: 2 added, 0 changed, 1 destroyed.**
# AWS 콘솔에서는 아래 이미지와 같이 확인 가능합니다
- 기존에 있던 인스턴스(TEST-Name_Change) 인스턴스는 terminated!
- 새롭게 TEST-WEB 서버가 잘 launch 되었습니다
여전히 -2d 존은 지못미...
- 보안 그룹도 Tag와 인바운드 규칙이 잘 설정되어 생성되었습니다.
- user_data테스트 방법도 간단합니다.
- 웹 브라우저에 생성된 EC2 인스턴의 :8080 을 입력하시면 Hello, World 가 출력되는 것을 확인 할 수 있습니다.
- 명령어를 이용한 테스트 방법도 아래와 같이가능합니다
$ curl <Public IP>:8080
> Hello, World
2.5 구성 가능한 웹 서버 배포
DRY (Don't Repeat Yourself) 원칙 : 반복하지 말라
코드 내에서 모든 정보는 유일하고 모호하지 않으며, 믿을 만한 형태로 존재해야 합니다.
- 테라폼은 입력 변수를 정의하게 하므로 코드가 중복되지 않고 구성을 관리하기도 쉽습니다.
# 변수를 선언하는 구문
variable "NAME" {
[CONFIG ...]
}
# 변수 선언 본문에는 세 개의 매개변수(Parameter)가 포함될 수 있으며, 모두 선택적 매개변수입니다.
- 세 가지 매개변수(parameter)
- description
- default
- 변수에 값을 전달하는 여러가지 방법
- CLI (-var 옵션 사용)
- 파일 (-var-file 옵션 사용)
- 환경 변수 ("TF_VAR_")
- 변수에 값을 전달하는 여러가지 방법
- type
- 유형에 대한 제약 조건(constraint)로 사용자가 전달하는 변수의 유형을 지정 가능
- 테라폼에서는 string, number, bool, list, map, set, object, tuple 등의 제약 존재
- 유형을 지정하지 않으면 any로 간주
# 입력 변수의 예시
variable "number_example" {
description = "An example of a number variable in Terraform"
type = number
default = 42
}
# user_data 스크립트에도 변수를 사용 가능
# 문자열 literal 내에서 참조를 사용하려면 interpolation(보간법) 유형의 표현식 사용 필요
"${...}"
# 아래 예시를 참고 부탁드립니다 🤓
<<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p ${var.server_port} &
EOF
# 출력 변수
# 입력 변수 뿐만 아니라 출력 변수도 정의 가능
output "<NAME>" {
value = <VALUE>
[CONFIG ...]
}
- NAME: 출력 변수 이름
- VALUE: 출력하려는 테라폼 표현식
- CONFIG 는 아래 두 가지 선택적 매개변수를 추가로 포함 가능
- description
- sensitive
- terraform apply 명령어 실행 후, 출력을 기록하지 않도록 하기위해서는 sensitive 를 true로 설정
- 보안상 민감한 자료 및 secret이 포함되어 있는 경우 유용
- terraform apply 명령어 실행 후, 출력을 기록하지 않도록 하기위해서는 sensitive 를 true로 설정
# 예를 들어 서버의 IP 주소를 찾기 위해, EC2 콘솔에서 수동으로 조회하는 대신 IP 주소를 출력 변수로 제공
output "public_ip" {
value = aws_instance.server.public_ip
description = "The public IP address of the WEB"
}
- 속성 참조를 다시 사용 (aws_instance 리소스의 public_ip 속성 참조)
- terraform apply 후, terraform output 명령어를 통해 [출력 변수] 확인 가능
# tf apply 를 통해, output에 대한 배포 작업이 우선적으로 진행되어야 합니다.
# out put에 대한 배포가 진행되지 않았다면 아래와 같은 에러가 발생합니다.
# $ terraform output
# ╷
# │ Warning: No outputs found
# │
# │ The state file either has no outputs defined, or all the defined outputs are empty. Please define an output in your configuration with the `output` keyword and run `terraform refresh` for it
# │ to become available. If you are using interpolation, please verify the interpolated value is not empty. You can use the `terraform console` command to assist.
# ╵
$ tf output
public_ip = "3.36.43.52"
🌟 지금까지 작성한 코드 확인 🌟
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "server" {
ami = "ami-0ba5cd124d7a79612"
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.instance.id]
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p ${var.server_port} &
EOF
tags = {
Name = "TEST-WEB"
}
}
resource "aws_security_group" "instance" {
name = "TEST-WEB-sg"
ingress {
from_port = var.server_port
to_port = var.server_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "TEST-WEB-sg"
}
}
variable "server_port" {
description = "The port the server will user for HTTP requests"
type = number
default = 8080
}
output "public_ip" {
value = aws_instance.server.public_ip
description = "The public IP address of the WEB"
}
- 지금까지 학습한 내용을 반영한 main.tf 파일은 위와 같습니다.
- 진행하면서 파일 용도에 맞게 main.tf 파일에서 변수, output 등이 분리가 되도록 구성되면 좋을 것 같네요 😍
꿀팁-1 🍯 - Formatting 명령어
# fmt 명령어
# fmt 명령어를 활용하시면 terraform 구조에 맞게 코드를 정렬해줍니다.
$ terraform fmt
꿀팁-2 🍯 - 인스턴스의 user_data 관련 AWS 콘솔에서 확인하기
- AWS EC2 대시보드 → 확인이 필요한 인스턴스 선택 → 작업 → 인스턴스 설정 → 사용자 데이터 편집 클릭
- 위 이미지와 같이 사용자 데이터에 대해 확인이 가능합니다.
# 호기심 천국
# var.server_port 변수 설정 및 apply시, 인스턴스가 새로 생성될 줄 알았지만 아래 명령어처럼 변경 없이 진행됨
$ tf apply
aws_security_group.instance: Refreshing state... [id=sg-00859bbb37fb1f398]
aws_instance.server: Refreshing state... [id=i-054f1344a35d7ae8b]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
**Apply complete! Resources: 0 added, 0 changed, 0 destroyed.**
## 호기심 발동으로 인하여 terraform destroy 후, 새로 생성 진행
## 결론!
## (콘솔에서 보기에는)
## 변수를 참조해서 사용자데이터 입력(8080) = port 값(8080)을 from/to_port에 직접 입력
### (당연한 부분이지만...)
### 보기에는 동일하지만, 변수로 지정하는 것이 훨씬 더 코드가 이쁜 것 같습니다 😆
(선행) 꿀팁-3 🍯 - Destroy 명령을 통한 인프라 삭제
# 테라폼으로 생성한 인프라를 삭제할 때는 destroy 명령어를 사용합니다.
$ terraform destroy
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: **yes**
aws_instance.server: Destroying... [id=i-054f1344a35d7ae8b]
aws_instance.server: Still destroying... [id=i-054f1344a35d7ae8b, 10s elapsed]
aws_instance.server: Still destroying... [id=i-054f1344a35d7ae8b, 20s elapsed]
aws_instance.server: Still destroying... [id=i-054f1344a35d7ae8b, 30s elapsed]
aws_instance.server: Destruction complete after 40s
aws_security_group.instance: Destroying... [id=sg-00859bbb37fb1f398]
aws_security_group.instance: Destruction complete after 0s
**Destroy complete! Resources: 2 destroyed.
# 깔끔하게 인프라 삭제 완료**
계속해서 [웹 서버 클러스터 배포] 부분도 가시죠 👍
긴 글 읽어주셔서 감사합니다 🤓
(이번 글... 세 번째.. 마크다운 양식으로 글을 작성 중에 가독성을 높일 수 있는 방법을 확인한 것 같네요 🤔)
(그래도 일찍 발견해서 다행이라고 생각하며,,, 테스트 후에 일괄 적용하도록 하겠습니다)
(감사합니다 😘)
728x90
반응형
'Terraform' 카테고리의 다른 글
Terraform 101 Study - 1주차 (0) | 2024.06.16 |
---|---|
[Terraform] 2장. 왜 테라폼인가? (77~82p) (0) | 2021.07.13 |
[Terraform] 2장. 왜 테라폼인가? (45~60p) (0) | 2021.07.12 |
[Terraform] 1장. 왜 테라폼인가? (1~44p) (0) | 2021.07.12 |
[Terraform] 테라폼 학습 블로깅 시작 (0) | 2021.07.11 |