테라폼 (terraform)으로 aws 리소스 생성하기

Moon Blue의 IT 로그 📝·2024년 1월 10일
0

🔍 테라폼으로 aws 리소스를 다루는 방법을 단계별로 알아봅니다

✅ 로컬 PC에 terraform 설치

# MacOS 기준으로 설치

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

✅ 로컬 PC에 AWS CLI 설치

# MacOS 기준으로 설치

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

which aws
aws --version

✅ AWS IAM 유저 권한 추가

  • 테라폼으로 aws 리소스를 다루기 위해서는 특정 IAM 유저 권한이 필요합니다
  • 사용자 또는 사용자 그룹에서 권한을 추가할 대상을 선택합니다
  • 권한 추가 페이지에서 AdministratorAccess 를 선택하여 권한을 추가합니다

✅ AWS 액세스 키 생성

  • 테라폼으로 aws 리소스를 다루기 위해서는 액세스 권한이 필요합니다
  • 액세스 키를 생성하여 테라폼이 aws 리소스를 다룰 수 있는 접근권한을 부여합니다
  1. AWS 콘솔 로그인
  2. IAM > 사용자 > 사용자 선택
  3. 액세스 키 만들기 클릭
  4. Command Line Interface(CLI) 선택
  5. 설명 추가 및 생성

💡 액세스 키가 생성된 시점 정보를 확인하고 키를 다운로드 받을 수 있는 유일한 기회입니다
액세스 키를 안전한 곳에 다운로드 받고 잘 보관해야 합니다

✅ AWS configure 설정

  • 생성한 액세스 키에는 두가지 정보가 있습니다 (엑세스 키 + 시크릿 키)
  • AWS CLI 를 통해 액세스 키 와 몇가지 연동정보를 등록합니다
# AWS 구성정보 설정
aws configure

AWS Access Key ID [None]: <액세스 키> # 엑세스 키 아이디 
AWS Secret Access Key [None]: <스크릿 키> # 시크릿 키 아이디
Default region name [region]: 리전 영문명 # 영문으로 된 리전 명칭 (예 : us-east-1)
Default output format [format]: json # 출력 포맷

# 설정이 제대로 되었는지 확인
cat ~/.aws/credentials

✅ VPC 생성

  • 기본적인 VPC 에 대한 이해를 기반으로 리소스를 생성한다
  • 아래와 같이 생성할 VPC 구성요소를 나열하고 순차적으로 생성한다
  1. vpc
  2. subnet (public / private)
  3. security group
  4. routing table (with router)
  5. internet gateway

🔍 AWS CLI와 연결된 region 정보 가져오기

# 쉘에서 실행
aws configure get region

🔍 AWS CLI와 연결된 Availability Zone 정보 가져오기

# variables.tf

data "aws_availability_zones" "available" {
  state = "available"
}

output "aws_azs" {
  value = data.aws_availability_zones.available.names
}

# 쉘에서 실행하여 출력결과 확인
terraform plan

🔍 인프라 제공자 정보 등록 (AWS)

# provider.tf

provider "aws" {
  region = "us-east-1"
}

📑 VPC 생성 스크립트

# vpc.tf

# vpc 생성
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "main"
  }
}

# 서브넷 생성 (public)
resource "aws_subnet" "public01" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.0.0/20"

  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    Name = "public_subnet01"
  }
}

resource "aws_subnet" "public02" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.16.0/20"

  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    Name = "public_subnet02"
  }
}

# 서브넷 생성 (private)
resource "aws_subnet" "private01" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.32.0/20"

  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    Name = "private_subnet01"
  }
}

resource "aws_subnet" "private02" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.48.0/20"

  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    Name = "private_subnet02"
  }
}

# 인터넷 게이트웨이 생성
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "main"
  }
}

# 보안그룹 생성
resource "aws_security_group" "remote" {
  vpc_id = aws_vpc.main.id
  name = "remote"
  description = "remote"

  # 인바운드 규칙 설정
  ingress {
    from_port = 22              # 인바운드 시작 포트
    to_port = 22                # 인바운드 끝나는 포트
    protocol = "tcp"            # 사용할 프로토콜
    description = "ssh"         # 자세한 프로토콜 종류
    cidr_blocks = ["0.0.0.0/0"] # 허용할 IP 범위
  }
  
  # 아웃바운드 규칙 설정
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "web" {
  vpc_id = aws_vpc.main.id
  name = "web"
  description = "web"

  # 인바운드 규칙 설정
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    description = "http"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    description = "https"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # 아웃바운드 규칙 설정
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# 라우팅 테이블 생성
resource "aws_route_table" "rt" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "rt"
  }
}

# 라우팅 테이블과 서브넷 관계 설정
resource "aws_route_table_association" "public01" {
  subnet_id      = aws_subnet.public01.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "public02" {
  subnet_id      = aws_subnet.public02.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "private01" {
  subnet_id      = aws_subnet.private01.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "private02" {
  subnet_id      = aws_subnet.private02.id
  route_table_id = aws_route_table.rt.id
}
profile
What a Beautiful World~ 🌏

1개의 댓글

comment-user-thumbnail
2024년 1월 12일

너무 유익했습니다 감사합니다.

답글 달기