[스터디 전용/실습3] EC2 1대 배포 & 웹 서버 설정
??? 테라폼은 이뮤터블 immutable 한가요?
뮤터블 mutable 한가요? → p37 이뮤터블 : 인프라스트럭처의 상태를 변경할 때, 기존의 인프라스트럭처를 수정하거나 업데이트하는 것이 아니라 새로운 인프라스트럭처를 생성하여 이전 상태의 인프라스트럭처를 교체하는 방식을 위미한다.
EC2 1대를 배포하면서 userdata 에 웹 서버 설정 → 간단한 애플리케이션 설정 자동화
Ubuntu 22.04 LTS 사용
# 각자 편한 디렉터리를 생성해주시면 됩니다
cd ..
mkdir t101-1week-web
cd t101-1week-web
# Ubuntu 22.04 최신 AMI ID 확인
aws ec2 describe-images --owners 099720109477 \
--filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" "Name=state,Values=available" \
--query 'Images|sort_by(@, &CreationDate)[-1].[ImageId, Name]' --output text
# 변수 지정
UBUNTUID=ami-0572f73f0a5650b33
코드 파일 작성 : user_data 에 실행 명령어 작성
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$UBUNTUID"
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
배포 실행 : -auto-approve 자동 승인 기능 부여 옵션
# 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
curl을 날리면 응답 하지 않는다..
왜 안될까?
코드 파일 수정 : 보안 그룹 생성 후 연동
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$UBUNTUID"
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
배포 실행
# plan/apply
terraform plan
terraform apply -auto-approve
# 모니터링 : EC2 정보와 curl 접속 확인
PIP=3.39.22.130
혹은
PIP=$(terraform output -raw public_ip)
while true; do curl --connect-timeout 1 http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done
# (옵션) 리소스 생성 그래프 확인
terraform graph
# graph 확인 > 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot
확인
---
- 참조 reference 는 코드의 다른 부분에서 값에 액세스 할 수 있게 해주는 표현식
- PROVIDER : ‘aws’ 같은 공급자의 이름
- TYPE : ‘security_group’ 같은 리소스의 유형
- NAME : 보안 그룹 이름인 ‘instance’ 같은 리소스의 이름
- ATTRIBUTE : ‘name’ 과 같은 리소스의 인수 중 하나이거나 리소스가 내보낸 속성 중 하나
- <PROVIDER>_<TYPE>.<NAME>.<ATTRIBUTE>
- 보안 그룹은 id라는 주석을 내보내므로 이를 참조하는 표현식은 아래와 같음
- 하나의 리소스에서 다른 리소스로 참조를 추가하면 내재된 종속성이 작성됨
- 테라폼은 종속성 구문을 분석하여 종속성 그래프를 작성하고, 이를 사용하여 리소스를 생성하는 순서를 자동으로 결정함
- aws_security_group.instance.id
---
웹 서비스 포트 변경 : 8080 포트가 아닌 다른 포트로 변경하려면 어떻게 해야 될까?
# 모니터링
while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
# plan
terraform plan
# aws_instance.example must be replaced
-/+ resource "aws_instance" "example" {
...
~ user_data = "d91ca31904077f0b641b5dd5a783401396ffbf3f" -> "f1a1c16060740d7be18475c067c120a0eed366da"
# forces replacement
...
Changes to Outputs:
~ public_ip = "43.201.8.225" -> (known after apply)
# apply
terraform apply -auto-approve
# 웹 서버 접속 시도 : 터미널3에서 실행
# process 올라오는데 시간이 1~2분 정도 소요되어서, ec2 생성되면 1~2분 정도 후에 curl 접속이 가능하다
# EC2 Public IP가 어떻게 되나요? 유지? 변경?
PIP=<각자 자신의 EC2 IP>
PIP=54.180.123.229
혹은
PIP=$(terraform output -raw public_ip)
while true; do curl --connect-timeout 1 http://$PIP:9090/ ; echo "------------------------------"; date; sleep 1; done
terraform output
terraform output public_ip
terraform output -raw public_ip
PIP=$(terraform output -raw public_ip)
echo $PIP
curl $PIP:9090
아래 보면 userdata부분이 바뀌면 삭제 됐다가 다시 생성됩니다.
그래서 재생성되면서 ip도 변경됩니다.
- HCL
HCL HashiCorp configuration language은 하시코프사에서 IaC와 구성 정보를 명시하기 위해 개발된 오픈 소스 도구이다 - 링크 Link
- IaC는 수동 프로세스가 아닌 코드를 통해 인프라를 관리하고 프로비저닝 하는 것을 말함
- 테라폼에서 HCL이 코드의 영역을 담당한다. HCL은 쉽게 읽을 수 있고 빠르게 배울 수 있는 언어의 특징을 가진다.
- 인프라가 코드로 표현되고, 이 코드는 곧 인프라이기 때문에 선언적 특성을 갖게 되고 튜링 완전한 Turing-complete 언어적 특성을 갖는다.
- 즉, 일반적인 프로그래밍 언어의 조건문 처리 같은 동작이 가능하다. 자동화와 더불어, 쉽게 버저닝해 히스토리를 관리하고 함께 작업 할 수 있는 기반을 제공.
HCL을 사용하면 동일한 내용을 JSON으로 표현하는 것보다 더 간결하고 읽기 쉽게 작성할 수 있다
표현식
// 한줄 주석 방법1
# 한줄 주석 방법2
/*
라인
주석
*/
locals {
key1 = "value1" # = 를 기준으로 키와 값이 구분되며
myStr = "TF ♡ UTF-8" # UTF-8 문자를 지원한다.
multiStr = <<EOF
Multi
Line
String
with anytext
EOF
boolean1 = true # boolean true
boolean2 = false # boolean false를 지원한다.
deciaml = 123 # 기본적으로 숫자는 10진수,
octal = 0123 # 0으로 시작하는 숫자는 8진수,
hexadecimal = "0xD5" # 0x 값을 포함하는 스트링은 16진수,
scientific = 1e10 # 과학표기 법도 지원한다.
# funtion 호출 예
myprojectname = format("%s is myproject name", var.project)
# 3항 연산자 조건문을 지원한다.
credentials = var.credentials == "" ? file(var.credentials_file) : var.credentials
}
- 테라폼 블록
- 테라폼 블록 : 테라폼 구성을 명시하는 데 사용
terraform {
required_version = "~> 1.3.0" # 테라폼 버전
required_providers { # 프로바이더 버전을 나열
random = {
version = ">= 3.0.0, < 3.1.0"
}
aws = {
version = "4.2.0"
}
}
cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
backend "local" { # state를 보관하는 위치를 지정
path = "relative/path/to/terraform.tfstate"
}
}
- 테라폼 내에서 버전이 명시되는 terraform, module에서 사용 가능하며 버전에 대한 제약을 둠으로써 테라폼, 프로바이더, 모듈이 항상 의도한 정의대로 실행되는 것을 목적으로 한다.
- 버전 체계는 시맨틱 버전 관리 Semantic Versioning 방식을 따른다
# version = Major.Minor.Patch
version = 1.3.4
- 시맨틱 버전 관리 방식
- Major 버전 : 내부 동작의 API가 변경 또는 삭제되거나 하위 호환이 되지 않는 버전
- Minor 버전 : 신규 기능이 추가되거나 개선되고 하위 호환이 가능한 버전
- Patch 버전 : 버그 및 일부 기능이 개선된 하위 호환이 가능한 버전
- 버전 제약 구문은 다른 프로그램 언어에서의 종속성 관리 시스템과 흡사하다.
- = 또는 연산자 없음 : 지정된 버전만을 허용하고 다른 조건과 병기할 수 없다.
- != : 지정된 버전을 제외한다.
- >, >=, <, <= : 지정된 버전과 비교해 조건(부등호)에 맞는 경우 허용한다.
- ~> : 지정된 버전에서 가장 자리수가 낮은 구성요소만 증가하는 것을 허용한다.
- ~> x.y 인 경우 y 버전에 대해서만, ~> x.y.z인 경우 z 버전에 대해서만 보다 큰 버전을 허용한다
- ~> : 지정된 버전에서 가장 자리수가 낮은 구성요소만 증가하는 것을 허용한다.
테라폼 버전 required_version
cd ..
cd 03.start
버전 확인 후 수정
terraform {
required_version = "< 1.0.0"
}
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
결과는?!
다시 수정 후 init
terraform {
required_version = ">= 1.0.0"
}
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
확인
버전을 높여서 해보자
terraform {
required_version = ">= 1.0.0"
required_providers {
local = {
source = "hashicorp/local"
version = ">=10000.0.0"
}
}
}
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
버전이 맞지 않아서 실행 되지 않습니다.
다시 수정
terraform {
required_version = ">= 1.0.0"
required_providers {
local = {
source = "hashicorp/local"
version = ">= 2.0.0"
}
}
}
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
잘 작동된됩니다.
'study > T101 4기' 카테고리의 다른 글
T101 4기 3주차 첫번째 (0) | 2024.06.29 |
---|---|
T101 4기 2주차 두번째 (0) | 2024.06.22 |
T101 4기 2주차 첫번째 (0) | 2024.06.22 |
T101 4기 1주차 세번째 (0) | 2024.06.15 |
T101 4기 1주차 첫번째 (0) | 2024.06.15 |