2024. 6. 15. 23:52ㆍEKS@Terraform
- CloudNet에서 주관하는 Terraform 스터디 내용입니다
- 내용은 위 책 테라폼으로 시작하는 IaC 를 기준으로 정리하였습니다.
- 실습은 M1 macbook air 에서 진행했습니다.
- 매번 좋은 스터디를 진행해 주시는 CloudNet 팀 감사드립니다
- 잘못된 점, 업데이트된 지식, 다른 코멘트 언제나 환영입니다!
1. 테라폼이란?
환경설정이 꼬이지 않고, 또 재현이 쉽도록 코드로 인프라를 관리하는 툴이다.
모든 리소스에 대해서 지원이 가능하지는 않고, 클라우드 환경에서 사용하는 것을 기본으로 거기서 배포하는 인프라를 코드로 관리하는 것이다.
현재 테라폼에서 지원하는 프로바이더 리스트는 링크에서 확인할 수 있다.
스터디에서는 aws 에서 주로 배포할 것이다.
여담으로 (이 글을 보고계신 분이라면 다 알 내용이지만...) 지난 4월 IBM에 테라폼을 만든 해시코프가 인수되었다.
안 그래도 지난 2023년 8월에 오픈소스에서 MPL 라이선스로 정책을 변경해서 권한이 축소되었는데, 또 앞으로 추가로 유료화 될 수 있을 것 같기도 하다. 예의주시가 필요할 듯.
2. 실습 환경 설정 (1) - 테라폼 설치
- 터미널에 tfenv로 버전을 맞춰서 테라폼을 설치한다.
스터디 동안 버전은 1.8.5 로 통일해서 사용한다
brew install tfenv
tfenv list-remote # 가능한 모든 tfenv 버전 표시됨
tfenv install 1.8.5 #1.8.5 버전 설치
tfenv use 1.8.5 #1.8.5버전 활성화
# 버전 확인
terraform version
# 자동완성 추가
terraform -install-autocomplete
설치가 잘 되었음을 확인할 수 있다.
- 테라폼 코드 편집을 편하게 하기 위해서 vscode에 해시코프 extension 을 설치해 준다.
이후에 dependency 를 보기 위해서 .dot 파일을 생성하게 되는데, 이걸 편하게 시각화하기 위해서 graphviz extension 도 설치해준다.
3. 실습 환경 설정 (2) - aws 자격 증명 설정
- aws 계정과 IAM User 를 먼저 만든다
- awscli를 설치하고 버전을 확인한다 (미리 설치되어 있어서 생략)
# 설치
brew install awscli
# 버전 확인
aws --version
# 환경변수로 설정
export AWS_ACCESS_KEY_ID=myAccessKeY
export AWS_SECRET_ACCESS_KEY=mySecretKeY
export AWS_DEFAULT_REGION=ap-northeast-2
# aws config 로 설정
aws configure MY_CONFIG
이렇게 설정이 잘 되어있고, key와 region 도 잘 잡혀있는 것을 확인한다.
- 실습에서 default VPC을 확인하기 때문에 default VPC 가 잡혀있는지 확인하고 없을 경우 아래 링크를 참고해서 설정한다. 나는 잡혀있어서 따로 설정하지는 않았다. 아래와 같이 뜨면 성공.
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=true' | jq
https://www.44bits.io/ko/post/inspect_resources_in_default_vpc_by_aws_cl
AWS CLI로 기본 VPC 관련 리소스들 탐색하기
AWS 계정을 생성하면 VPC를 비롯한 여러 네트워크 자원이 함께 만들어집니다. 이 때 만들어지는 리소스들을 AWS CLI로 탐색하는 방법을 소개합니다.
www.44bits.io
4. aws 에서 테라폼으로 EC2 배포하기 (1)
우선 위에서 설정한 aws cli가 잘 되었다고 가정하고, EC2를 가져오기 위한 이미지 경로를 환경변수에 등록해 놓는다.
SSM은 Aws System Manager 의 약자로(약자가 이상하지만) 원격 호스트에 접속하기 위해 ssh 보다 개선된 새로운 방법이다. 무엇보다 별도로 bastion host, key pair 가 필요하지 않다는 것이 큰 장점이다.
참고: https://musma.github.io/2019/11/29/about-aws-ssm.html
AWS SSM으로 EC2 인스턴스에 접근하기 (SSH 대체)
목차 서론 들어가기: 더 좋은 방법 대상 독자 SSM: AWS Systems Manager 원격 호스트 접속 방법 비교: SSH (기존) vs. SSM (개선) S...
musma.github.io
# ec2 이미지 검색
aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId, Name]' --output text
# 사용할 이미지 경로 AL2ID 라는 환경변수에 저장
AL2ID=`aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId]' --output text`
echo $AL2ID
# SSM 파라미터 확인
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query 'Parameters[*].[Value, Name]' --output text
- 배포를 확인하기 위해 모니터링을 새 터미널에서 걸어놓는다
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
- EC2를 배포하는 간단한 테라폼 코드를 저장한다. 파일명은 main.tf 여야 한다
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "$AL2ID"
instance_type = "t2.micro"
}
- 그러면 이제 진짜! 본격적으로 배포를 실행해보자
1. 이 디렉토리에 테라폼이 있음을 인지시켜 준다. tree 명령어로 의존성을 확인할 수 있다
terraform init
tree .terraform
2. plan 으로 어떤 작업을 실행할지를 미리 확인하고 코드의 의도와 맞는지 확인한다.
terraform plan
이번 plan 에서는 t2.micro 를 배포할 것이라는 것을 알 수 있다
3. 배포
terraform apply
apply command 로 배포를 실행한다.
아까 띄워놓은 모니터링에서도 배포가 잘 되었음을 확인할 수 있다.
- 배포를 진행하고 나면 (plan 단계에서도) 테라폼의 꽃인 state 가 생성된다. 테라폼은 state의 데이터로 리소스를 탐색하고 추적하기 때문에 매우!! 중요!! 하다
기본적으로는 실행한 로컬에 .tfstate 파일이 저장되지만 여러 사람이 작업하고 있을 경우에는 s3 등의 타 스토리지를 사용해서 참여자 모두가 tfstate 파일을 공유하고 있어야 한다. backend 를 로컬로 주지 않으면 여러사람이 동시에 state을 작업해서 엉키지 않게끔 .terraform.tfstate.lock.info 파일이 생성되어 접근을 방지한다.
- dependency 를 확인하기 위해서 graph 명령어를 사용하여 dot file을 export 할 수도 있다
terraform graph > graph.dot
이번에 생성한 t2.micro EC2 의 그래프이다. 아무 dependency 없이 간단하다.
dot file 은 텍스트파일이므로, 시각회해서 이미지 형태로 열려면 처음에 언급한 Graphviz 같은 extension 을 사용하면 좋다.
- 삭제
terraform destroy
destroy 하고 난 다음에도 tfstate 는 남아 있어서 다시 그래도 올릴 수 있는 것이 큰 장점일 듯 하다.
그리고 터미널로 관리하면 까먹고 삭제 안한 리소스들이 나오기 마련인데 (저도 알고 싶지 않았습니다) 이런 걸 확실히 관리해 줄 수 있는 것이 큰 장점으로 다가왔다. 지난달에 리소스 하나 까먹고 안 꺼서 치킨 두 마리 날려서 더 그런 것 같다.
5. aws 에서 테라폼으로 EC2 배포하기 (2)
- 앞에서는 단순하게 리소스만 띄우고 끝냈지만 이번에는 필요한 애플리케이션 설정도 같이 자동화해 볼 것이다.
이번에는 아마존리눅스 대신 우분투 이미지를 사용해서 간단한 웹서버를 설정해 볼 것이다
# 우분투 이미지 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
웹서버로 쓸 인그레스 1개, EC2 t2.micro 1개를 배포하는 테라폼 파일을 작성한다
이전과 비교해 t2.micro에는 새로운 정보인 vpc security group id 와 tag를 추가했다.
인스턴스로의 접속을 도와줄 ingress 도 추가되었다.
마지막으로 output 을 설정해 사용자가 접속 정보를 알 수 있도록 했다.
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"
}
- 파일을 작성했으니 테라폼으로 배포해 보자
terraform init
terraform plan
terraform apply
# 확인 없이 apply
# terraform apply -auto-approve
- 이제 모니터링 코드를 사용해서 인그레스를 통해 인스턴스에 접속이 가능한지 확인해보자
while true; do curl --connect-timeout 1 http://$PIP:8080/ ; echo "------------------------------"; date; sleep 1; done
접속이 잘 되는 것을 확인하였다.
- 의존성을 확인하기 위해 그래프를 그려보았다. 이번에는 의존성이 발생했는데, 화살표가 출발하는 쪽이 먼저 실행된다.
이번 경우에는 1.인스턴스가 먼저 생성되고 2. security group이 생성됨을 알 수 있다
6. 테라폼으로 배포된 인스턴스 수정하기
- 인스턴스 수정을 실습하기 위해 접근 포트를 8080 에서 9090로 바꿔 보았다.
- 우선 main.tf 파일을 아래 내용과 같이 수정한다. 이전에 사용한 파일에서 포트번호만 8080 -> 9090 으로 바뀌었다.
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 9090" > index.html
nohup busybox httpd -f -p 9090 &
EOF
user_data_replace_on_change = true
tags = {
Name = "Single-WebSrv"
}
}
resource "aws_security_group" "instance" {
name = var.security_group_name
ingress {
from_port = 9090
to_port = 9090
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"
}
- terraform plan 으로 변경 내용을 확인한다. EC2 의 user_data 가 변경됨을 알 수 있다.
- terraform apply 로 파일을 반영한다.
EC2 인스턴스가 삭제된 후 user_data 를 새로 반영하여 생성됨을 볼 수 있다.
- 배포 완료와 함께 표시되는 public ip로 모니터링 코드의 접속주소와 포트를 고치고 접속을 시도한다
8080포트로는 접근 실패, 9090포트로는 접근 성공을 확인할 수 있다.
- terraform destroy 로 배포한 리소스를 삭제하며 실습을 종료한다. AWS GUI 콘솔에서도 잘 삭제되었음을 볼 수 있다.
실제 클러스터를 관리하는 역할을 맡아 본 적이 없음에도 테라폼이 굉장히 센세이셔널 하고 편하게 느껴졌다. 지난달에 인스턴스 안 꺼서 요금 낸 게 이번 스터디를 즐겁게 하라는 빅픽처였나? 싶을 정도로. 스터디 끝날 무렵에는 리소스를 편리하게 관리할 수 있게 될 것 같아 기쁘다.
'EKS@Terraform' 카테고리의 다른 글
[Terraform@CloudNet] Terraform Runner: Atlantis (0) | 2024.07.13 |
---|---|
[Terraform@CloudNet] Terraform Module (0) | 2024.07.13 |
[Terraform@CloudNet] Terraform State (0) | 2024.07.07 |
[Terraform@CloudNet] Terraform Provider (0) | 2024.07.06 |
[Terraform@CloudNet] Terraform 기본 사용 (2) (2) | 2024.06.23 |