# 목표아키텍처를 기반으로 테라폼 코드를 활용한 인프라 구성
1. 목표 아키텍처
- 목표 아키텍처 리소스
VPC, 인터넷 게이트웨이, NAT 게이트웨어, EC2 인스턴스, 퍼블릭 서브넷 2개, 프라이빗 서브넷 2개, ap-northeast-2 A-C
- 위와 같이 목표 아키텍처를 정의 하였고, 실행한 아파치 웹서버로 접근을 하게 되면 아래와 같은 페이지를 출력하게 된다.
2. 테라폼 코드 살펴보기
- 일단 모듈로 구성을 했기때문에 폴더 구조는 아래와 같다.
- Root 경로의 파일을 정의하여 해당 모듈인 vpc 및 ec2를 실행하여 리소스를 생성하는 구조이다.
- ec2 폴더
main.tf
# RSA 알고리즘을 이용해 private 키 생성
resource "tls_private_key" "pk" {
algorithm = "RSA"
rsa_bits = 4096
}
# private 키를 가지고 keypair 파일 생성
resource "aws_key_pair" "kp" {
key_name = var.key_name
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
}
# EC2 인스턴스 생성 (Public)
resource "aws_instance" "webserver" {
ami = var.ami_number
instance_type = var.instance_type
key_name = var.key_name
subnet_id = var.public_subnet
vpc_security_group_ids = ["${aws_security_group.webserversg.id}"] # 내부에 생성된 리소스를 참조
user_data = <<-EOF
#!/bin/bash
sudo yum install -y httpd
echo "zzanggu의 웹서버 테스트 중..." > /var/www/html/index.html
sudo systemctl start httpd
sudo systemctl enable httpd
EOF
# shellscript 사용을 위한 설정
provisioner "local-exec" {
command = "echo \"Hello, World from $(uname -smp)\""
}
# 태그값 설정
tags = {
Name = "webserver"
}
# depends_on = ["aws_internet_gateway.igw"]
}
resource "aws_eip" "webserver" {
vpc = true
instance = aws_instance.webserver.id
# depends_on = [aws_internet_gateway.igw]
}
resource "aws_security_group" "webserversg" {
name = "webserversg"
description = "allow 22, 80"
vpc_id = var.vpc_id
}
resource "aws_security_group_rule" "websg_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.webserversg.id
description = "ssh"
}
resource "aws_security_group_rule" "websg_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.webserversg.id
description = "http"
}
resource "aws_security_group_rule" "websg_outbound" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.webserversg.id
description = "outbound"
}
output.tf
output "public_ip" {
value = aws_instance.webserver.public_ip
description = "The public IP of the Instance"
}
variables.tf
variable "ami_number" {
type = string
}
variable "instance_type" {
type = string
}
variable "key_name" {
type = string
}
variable "public_subnet" {
type = string
}
variable "vpc_id" {
type = string
}
- vpc 폴더
main.tf
# VPC 생성
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr_block
tags = {
Name = "terraform_vpc_seungkim"
}
}
# Public 서브넷 생성
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_block
}
# Public-A 서브넷 생성
resource "aws_subnet" "public-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_block-a
}
# Private 서브넷 생성
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidr_block
}
# Private-A 서브넷 생성
resource "aws_subnet" "private-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidr_block-a
}
# 인터넷 게이트웨이 생성
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
# EIP 생성
resource "aws_eip" "nat" {
vpc = true
}
# NAT 게이트웨이 생성
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public.id
}
# 퍼블릭 라우팅 테이블 생성
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}
# 프라이빗 라우팅 테이블 생성
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.main.id
}
}
# 라우팅 테이블 연결 (퍼블릭 서브넷)
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
# 라우팅 테이블 연결 (퍼블릭 서브넷-a)
resource "aws_route_table_association" "public-a" {
subnet_id = aws_subnet.public-a.id
route_table_id = aws_route_table.public.id
}
# 라우팅 테이블 연결 (프라이빗 서브넷)
resource "aws_route_table_association" "private" {
subnet_id = aws_subnet.private.id
route_table_id = aws_route_table.private.id
}
# 라우팅 테이블 연결 (프라이빗 서브넷-a)
resource "aws_route_table_association" "private-a" {
subnet_id = aws_subnet.private-a.id
route_table_id = aws_route_table.private.id
}
output.tf
output "vpc_id" {
value = aws_vpc.main.id
description = ""
}
output "public_subnet_id" {
value = aws_subnet.public.id
description = ""
}
output "private_subnet_id" {
value = aws_subnet.private.id
description = ""
}
variables.tf
variable "vpc_cidr_block" {
type = string
}
variable "public_subnet_cidr_block" {
type = string
}
variable "public_subnet_cidr_block-a" {
type = string
}
variable "private_subnet_cidr_block" {
type = string
}
variable "private_subnet_cidr_block-a" {
type = string
}
- Root 폴더
provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.27.0"
}
}
}
provider "aws" {
region = "ap-northeast-2"
}
ec2.tf
module "ec2" {
source = "../ec2"
ami_number = "ami-00000000000000"
instance_type = "t2.micro"
key_name = "webserver"
public_subnet = "subnet-00000000000000"
vpc_id = "vpc-0000000000000"
}
vpc.tf
module "vpc" {
source = "../vpc"
vpc_cidr_block = "10.0.0.0/16"
public_subnet_cidr_block = "10.0.0.0/24"
public_subnet_cidr_block-a = "10.0.0.0/24"
private_subnet_cidr_block = "10.0.0.0/24"
private_subnet_cidr_block-a = "10.0.0.0/24"
}
output.tf
output "vpc_id" {
value = module.vpc.vpc_id
description = ""
}
output "public_subnet_id" {
value = module.vpc.public_subnet_id
description = ""
}
output "private_subnet_id" {
value = module.vpc.private_subnet_id
description = ""
}
3. Terraform Code 수정하기 :: Subnet에 tag 값 입력하여 업데이트하기
- 테라폼 코드를 활용하여 인프라를 생성하면 Subnet의 이름이 아래와 같이 빈칸으로 입력되어 나온다.
해당 값을 부여하기 위해서는 tag값을 따로 지정해 줘야 한다. tag 값을 부여하여 업데이트를 진행해보자.
- tag 값은 terraform_vpc_seungkim_public_subnet 을 기본으로 이와같은 방법으로 태그값을 설정해보자.
① 일단 서브넷 리소스를 찾는다. vpc → main.tf 파일에 정의된 서브넷 리소스를 찾고 tag 값을 부여한다.
② 코드 수정 :: subnet 리소스를 찾아 아래와 같이 tag 값을 부여한다.
- vpc 폴더 → main.tf 파일을 아래와 같이 수정
# Public 서브넷 생성
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_block
tags = {
Name = "terraform_vpc_seungkim_public_subnet"
}
}
# Public-A 서브넷 생성
resource "aws_subnet" "public-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_block-a
tags = {
Name = "terraform_vpc_seungkim_public_subnet-a"
}
}
# Private 서브넷 생성
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidr_block
tags = {
Name = "terraform_vpc_seungkim_private_subnet"
}
}
# Private-A 서브넷 생성
resource "aws_subnet" "private-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidr_block-a
tags = {
Name = "terraform_vpc_seungkim_private_subnet-a"
}
}
③ terraform plan, terraoform apply 를 통해 변경된 내용을 적용한다.
- terraform plan을 적용하면 추가되는 태그값을 확인할 수 있다.
- terraform apply를 적용 후 subnet 리스트를 보면 아래와 같이 name 값이 업데이트 된 것을 확인할 수 있다.
④ tag 값을 변수로 설정하는 방법
- 예시로 public subnet 리소스를 확인해보자.
vpc → main.tf
# Public-A 서브넷 생성
resource "aws_subnet" "public-a" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_block-a
tags = {
Name = "${var.public_subnet_name-a}"
}
}
vpc → variables.tf
variable "public_subnet_name-a" {
type = string
}
Root → vpc.tf
public_subnet_name-a = "terraform_vpc_seungkim_public_subnet-a"
이상 오늘은 여기까지...
'♻ Terraform(테라폼) > Architecture 구성' 카테고리의 다른 글
Terraform을 활용한 인프라 설계 01 (0) | 2022.12.12 |
---|