** AWS를 사용하였음.
클라우드 환경에서 서비스가 점점 커짐에 따라 관리해야 하는 서버가 늘어난다.
설정 변경이 될 때마다 aws 콘솔에 들어가서 하나씩 수정한다..
관리해야 하는 서버가 수십대라면? 리전이나 계정을 옮긴다면..?
이제 인프라도 코드로 관리하자!
흔하게 사용되는 Terraform
에 대해서 알아보자.
Terraform 설치
# 테라폼 버전 관리 도구 brew install tfenv # 버전 확인 tfenv --version # 테라폼 설치 - version을 명시하지 않으면 최신 버전 설치 tfenv install {version} # 여러 버전을 사용 중일때 사용 버전 지정 tfenv use {version}
.tf
로 끝나는 확장자를 가진 파일로 구성된다..tf
파일들을 실행한다.Terraform 주요 명령어
# 초기화
terraform init
# 실행 계획
terraform plan
# 적용
terraform apply
# 삭제
terraform destroy
간단하게 EC2에 nginx를 띄워보자.
terraform
을 사용하기 위해IAM
계정을 하나 생성한다.
- 어드민 권한을 주자.
- access key 생성
- secret key는 다시 볼 수 없으니 잘 저장해 두자.
aws cli 설치
brew install awscli
aws 설정
aws configure
- 위에서 생성한
access key
,secret key
를 입력하자.
~/.aws
디렉토리 아래에config
,credentials
아래에 파일이 저장되고aws cli
를 사용할 때 해당 권한, 설정을 가지고 사용한다.
provider.tf
provider "aws" {
region = "ap-northeast-3"
}
# 사용 가능한 가용영역
data "aws_availability_zones" "available" {
state = "available"
}
VPC, subnet 등 네트워크 설정
resource
뒤에는 aws의 서비스 명을 적고 그 다음에는 코드에서 사용할 해당 리소스의 이름을 적는다.
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
"Name" = "vpc"
}
}
resource "aws_subnet" "subnet" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.0.1.0/24"
tags = {
"Name" = "subnet"
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc.id
tags = {
Name = "igw"
}
}
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "rt"
}
}
resource "aws_route_table_association" "rta" {
subnet_id = aws_subnet.subnet.id
route_table_id = aws_route_table.rt.id
}
ingress
: 인바운드 트래픽 설정80
포트와 ssh 접근을 위한 22
포트를 열었다.egress
: 아웃바운드 트래픽 설정resource "aws_security_group" "sg" {
name = "sg"
vpc_id = aws_vpc.vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags ={
"Name" = "test-sg"
}
}
pem
키를 생성하고 등록한다.resource "tls_private_key" "pk" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "aws_key_pair" "kp" {
key_name = "terraform"
public_key = tls_private_key.pk.public_key_openssh
}
resource "local_file" "ssh_key" {
filename = "${aws_key_pair.kp.key_name}.pem"
content = tls_private_key.pk.private_key_pem
}
init.sh
#/bin/bash
sudo yum update -y
sudo yum install docker -y
sudo systemctl start docker
sudo usermod -aG docker ec2-user
sudo systemctl enable docker
sudo docker run --name=nginx -d -p 80:80 nginx
인스턴스의 ami 값은 리전마다 다를 수 있으니 주의!
- 인스턴스 생성할 때 볼 수 있다.
web.tf
resource "aws_instance" "web" {
ami = "ami-0f19932fc7b89784a"
instance_type = "t3.small"
subnet_id = aws_subnet.subnet.id
vpc_security_group_ids = [aws_security_group.sg.id]
key_name = aws_key_pair.kp.key_name
associate_public_ip_address = true # public ip 생성
# 로컬에 있는 파일을 원격지로 복사
provisioner "file" {
source = "./script/init.sh"
destination = "/home/ec2-user/init.sh"
connection {
type = "ssh"
host = self.public_ip
user = "ec2-user"
private_key = tls_private_key.pk.private_key_pem
}
}
# 원격지에 커맨드 실행
provisioner "remote-exec" {
inline = [
"chmod +x /home/ec2-user/init.sh",
"/home/ec2-user/init.sh"
]
connection {
type = "ssh"
host = self.public_ip
user = "ec2-user"
private_key = tls_private_key.pk.private_key_pem
}
}
tags = {
Name = "web-server"
}
}
# 테라폼 실행 후 출력 값
output "web_public_ip" {
value = self.public_ip
}
terraform init
terraform plan
-auto-approve
옵션은 실행여부를 묻지 않고 바로 실행한다.terraform apply -auto-approve
ssh -i terraform.pem ec2-user@15.152.69.231
테스트 용도라면 반드시 종료 시켜주자.
-auto-approve
옵션은 실행여부를 묻지 않고 바로 실행한다.terraform destroy -auto-approve