일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- gitlab.rb
- shanta #bahadur
- RequestFacade
- secretid
- Session invalidate
- CQRS
- 하만카돈 #오라 #스튜디오 #2 #harman #kardon #aura #studio #fix #repair #수리 #shutdown #bluetooth
- WooWaCon
- external_url
- AWS SNS
- KMS
- 멱등성
- backtick
- approle
- auth method
- 명령어 대체
- 우아콘
- gitlab-ctl
- InheritableThreadLocal
- Approval Test
- AWS SQS
- hashicorp
- Unseal
- Shamir
- JSR-330
- Vault
- 제어역전
- MSA
- 샤미르
- json.tool
- Today
- Total
인생은 여행
Terraform 101 Day1 본문
이 글은 도서 "테라폼으로 시작하는 IaC"를 교재로 하여 진행하는 가시다님의 Terraform 101 스터디 4기에 참여하여 기록으로 남긴 것입니다.
IaC
"IaC는 컴퓨터에서 읽을 수 있는 정의 파일을 사용해 인프라나 서비스를 관리하고 프로비저닝하는 프로세스"
긍정적인 측면
- 속도와 효율성
- 버전 관리
- 협업
- 재사용성
- 기술의 자산화
우려되는 측면
- 코드 문법 학습
- 파이프라인 통합
- 대상 인프라에 대한 이해 필요
테라폼의 세 가지 중요한 철학
- 워크플로에 집중
- 코드형 인프라(IaC)
- 실용주의
테라폼 제공 유형
- On-Premise
- Hosted SaaS
- Private Install
실습 1: 테라폼 설치
사용하는 컴퓨터 환경이 mac이므로 brew 명령을 이용하여 설치할 수도 있지만 다루는 테라폼 소스마다 요구하는 테라폼 버전이 다를 수 있으므로 스터디에서는 tfenv라는 프로그램을 먼저 설치하고 tfenv를 통하여 테라폼을 설치하는 방식으로 진행하였다.
기존에 이미 brew를 이용하여 테라폼이 설치되어 있었지만 tfenv가 테라폼 바이너리를 관리할 수 있도록 제거하고 tfenv를 이용하여 다시 설치하였다.
# tfenv 설치
brew install tfenv
# terraform 설치 및 기본 버전 선택
tfenv list-remote
tfenv install 1.3.2
tfenv use 1.3.2
tfenv list
terraform version
# 자동완성 - 현재 계정의 시작 스크립트에 테라폼 자동완성 기능 기동 명령 추가
terraform -install-autocomplete
실습 2: default VPC에 EC2 1대 배포
꿀팁 - 다음은 메모해두고 업무에 활용해 볼만할
특정 AMI 검색하기
# SSM Parameter에서 Amazon Linux 최신 버전 이름 조회
aws ssm get-parameters-by-path \
--path /aws/service/ami-amazon-linux-latest \
--query "Parameters[].Name"
# SSM Parameter에서 이미지 이름으로 최신 AMI 버전 찾기
aws ssm get-parameters-by-path \
--path /aws/service/ami-amazon-linux-latest \
--query "Parameters[?contains(Name, 'amzn2-ami-kernel-5.10-hvm-x86_64-gp2')]"
# AMI 중에서 조회 및 정렬
aws ec2 describe-images --owners self amazon \
--query "sort_by(Images[?contains(Name, 'amzn2-ami-kernel-5.10-hvm-')], \
&CreationDate)[*].[ImageId, Name]" \
--output text
참고
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html
[토막 상식] 아미존 리눅스 2는 커널버전 4.14와 5.10을 지원한다. 이미지 이름에 커널 버전이 없으면 4.14이다.
- https://docs.aws.amazon.com/linux/al2/ug/aml2-kernel.html
현재(2024.06.16) 최신 버전
- ami-0d7acf3d584720d31 amzn2-ami-kernel-5.10-hvm-2.0.20240610.1-arm64-gp2
- ami-06f220419a1559609 amzn2-ami-kernel-5.10-hvm-2.0.20240610.1-x86_64-ebs
- ami-034a31ed1d34ef024 amzn2-ami-kernel-5.10-hvm-2.0.20240610.1-x86_64-gp2
EC2 생성 모니터링 준비(주기적으로 EC2 목록을 보여주므로 계정에 이미 인스턴스가 있다면 조회 조건을 조정한다)
export AWS_PAGER=""
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
아래와 같은 내용으로 main.tf 파일을 작성한다.
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0c76973fbe0ee100c"
instance_type = "t2.micro"
}
아래와 같은 명령으로 인스턴스를 생성한다.
# 초기화
terraform init
# 계획
terraform plan
# 실행
terraform apply
생성된 인스턴의 정보를 수정한다. 여기에서는 태그를 하나 추가하였다.
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0c76973fbe0ee100c"
instance_type = "t2.micro"
tags = {
Name = "t101-study"
}
}
plan 후 apply 한다.
다음은 최신 AMI를 코드로 가져오는 예제이다.
provider "aws" {
region = "ap-northeast-2"
}
# plan에서 ami id가 보이지 않는다. 파라미터 조횟값이라 민감정보로 판단하는 듯 하다. "(sensitive value)"로 표시
data "aws_ssm_parameter" "amzn2_latest" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2"
}
# plan 시 ami id가 보인다.
data "aws_ami" "linux" {
owners = ["amazon"]
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-kernel-5.10-hvm*"]
}
}
resource "aws_instance" "example" {
#ami = data.aws_ssm_parameter.amzn2_latest.value
ami = data.aws_ami.linux.id
instance_type = "t2.micro"
tags = {
Name = "Sample EC2"
}
}
실습 3: default VPC에 웹 서버 배포
Ubuntu 22.04 LTS 사용 (ami-0e9bfdb247cc8de84)
EC2의 userdata를 이용하여 인스턴스 기동시에 웹서버를 띄운다.
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0e9bfdb247cc8de84"
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"
}
}
- 웹서버 접속 확인
# [터미널3] 변수 지정
PIP=<각자 자신의 EC2 IP>
while true; do curl --connect-timeout 1 http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done
접속 실패, 웹 서버 접속이 왜 되지 않을까요?
-> AWS에서는 외부에서의 접속을 기본적으로 차단한다. 보안그룹 설정을 통해 서비스하는 포트를 외부로 개방해 주어야 한다.
코드에 보안그룹 설정을 추가한다.
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-0e9bfdb247cc8de84"
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"
}
위에서 vpc_security_group_ids = [aws_security_group.instance.id] 부분은 보안그룹의 ID를 인스턴스에서 참조하는 모양새이다.
테라폼은 종속성 구문을 분석하여 종속성 그래프를 작성하고, 이를 사용하여 리소스를 생성하는 순서를 자동으로 결정한다.
포트를 8080 -> 9090으로 변경하기 위해서는 코드 내의 8080을 모두 9090으로 바꿔줘야한다. 만약 빈번하게 서버의 포트가 변경되면 어떻게 해야 될까요? 이런 불편함을 해결하려면 어떻게 해야 될까요?
-> 포트 번호를 변수 처리하여 코드 한 곳에서만 변경하거나 외부에서 주입할 수도 있을 것이다.
만약 user_data_replace_on_change = false 설정 상태에서 userdata 를 변경 후 apply 하면 어떻게 될까요?
-> 어찌된 일인지 EC2가 재기동하였지만 접속불가 상태가 됨. 더 확인 필요
인프라 배포 후 애플리케이션 설정 할 수 있는 다양한 방법이 있고 장단점이 있습니다. 좀 더 견고하고 안정적이며 신뢰할 수 있는 방법이 무엇일까요? - 참고링크 링크 - 테라폼 코드 userdata 사용, cloud-init 사용, Packer 활용, Provisiner Connections 활용, 별도의 설정 관리 툴 사용(Chef, Habitat, Puppet 등)
심화옵션: 코드와 실제 배포된 형상이 일치하지 않을 경우
테라폼 apply를 하면 적용된 인프라의 상태가 terraform.tfstate 파일에 기록된다. 이 상태 파일이 없으면 테라폼 코드를 정상적으로 수행할 수 없다. 상태는 아주 중요하므로 유실되지 않도록 유의해야 한다.
IaC 도입 시에는 최대한 코드를 통한 상태가 실제 배포된 프로바이더의 상태가 되도록 맞추는 것이 중요.
상태를 로컬 파일이 아닌 다른 곳에 저장할 수 있다. S3도 좋은 대안이 될 수 있다.
[이론] Variable 변수
입력 변수
변수의 4가지 입력 방안
variable "server_port" {
description = "The port the server will use for HTTP requests"
type = number
}
- 대화형으로 변수값 입력
default 값이 없고, 아무런 옵션이 주어지지 않았다면 실행시에 물어본다.
- -var 옵션
- 환경 변수
# 환경변수에 지정
export TF_VAR_server_port=8080
terraform plan
# 환경변수 확인
export | grep TF_VAR_
# 환경변수 지정 삭제
unset TF_VAR_server_port
- 디폴트 값을 미리 지정
variable "server_port" {
description = "The port the server will use for HTTP requests"
type = number
default = 8080
}
출력 변수
출력 변수 용도
- 유용한 정보 출력
- 모듈의 리턴 값