카테고리 없음

[AWS] aws 과금 방지를 위한 체크리스트 + Terraform

챛채 2025. 3. 5. 12:45

1. AWS 실습 후 꼭 해야 하는 삭제 체크리스트 ✔️

 

[ ✔️ ] EC2 인스턴스 종료 및 삭제  
[ ✔️ ] EBS 볼륨 삭제 (남아있는지 꼭 확인)  
[ ✔️ ] Elastic IP 해제 및 삭제  
[ ✔️ ] RDS (DB) 삭제  
[ ✔️ ] S3 버킷 삭제 (필요하면 백업 후)  
[ ✔️ ] VPC 삭제  
[ ✔️ ] 로드밸런서 삭제  
[ ✔️ ] CloudWatch 알람 같은 모니터링 설정 해제  
[ ✔️ ] 비용 확인 (Billing 메뉴)

2. AWS 요금 알림 설정하기

설정 방법:

  1. AWS 콘솔 접속
  2. 상단 검색창에 "Billing" → "Budgets" 이동
  3. "예산 생성하기" 클릭
  4. 예산 이름 작성 (ex. 실습 요금 알림)
  5. 월 예산 $1~$5 정도로 설정
  6. 이메일 주소 입력 → 알림 받기

3. Terraform 활용하기

Terraform은 AWS 같은 클라우드 리소스를 코드로 만들어서 관리하는 도구인데 로컬 PC나 서버에 설치를 한다.

Mac은 그냥 brew통해서 설치를해주고 리눅스에서는

sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform

 

설치 후 확인

terraform -v

 

그다음 AWS 연동을 설정해주는데 AWS에 접근할 수 있게 AWS CLI를 설치하고 인증

aws configure
//AWS Access Key ID
//AWS Secret Access Key
//리전 (ex. ap-northeast-2)
//출력 형식 (json)

입력 후 Terraform 기본 폴더 구조를 만드는데 아래와 같은 명령어를 사용하여 작성한다

mkdir my-terraform-project
cd my-terraform-project

 

예제 코드 -main.tf 

  • 아래와 같이 작성해두면 EC2 t2.micro 서버 하나를 서울 리전에 생성하게된다.
provider "aws" {
  region = "ap-northeast-2"  # 서울 리전
}

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"  # (예: Amazon Linux 2)
  instance_type = "t2.micro"
}

 

마지막으로 실행은 

terraform init      # Terraform 초기화
terraform plan      # 뭘 만들지 미리 보기
terraform apply     # 실제 생성!


//삭제
terraform destory #리소스 전체 삭제

 

 

4. Terraform에서 VPC + 서브넷 + EC2 + RDS 한 번에 만들기

  • provider.tf
provider "aws" {
  region = "ap-northeast-2"
}
  • vpc.tf
resource "aws_vpc" "main_vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "terraform-vpc"
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "terraform-public-subnet"
  }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "terraform-igw"
  }
}

 

  • security-group.tf
resource "aws_security_group" "web_sg" {
  name        = "web-sg"
  description = "Allow SSH, HTTP, and MySQL"
  vpc_id      = aws_vpc.main_vpc.id

  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTP"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "MySQL"
    from_port   = 3306
    to_port     = 3306
    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 = "terraform-web-sg"
  }
}

 

  • iam.tf
resource "aws_iam_role" "ec2_role" {
  name = "terraform-ec2-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Effect = "Allow",
      Principal = {
        Service = "ec2.amazonaws.com"
      },
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_instance_profile" "ec2_instance_profile" {
  name = "terraform-ec2-profile"
  role = aws_iam_role.ec2_role.name
}

 

 

  • ec2.tf
resource "aws_instance" "web_server" {
  ami                    = "ami-0c55b159cbfafe1f0"
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.public_subnet.id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  iam_instance_profile   = aws_iam_instance_profile.ec2_instance_profile.name

  tags = {
    Name = "terraform-ec2"
  }
}

 

  • rds.tf
resource "aws_db_subnet_group" "rds_subnet_group" {
  name       = "terraform-rds-subnet-group"
  subnet_ids = [aws_subnet.public_subnet.id]

  tags = {
    Name = "terraform-rds-subnet-group"
  }
}

resource "aws_db_instance" "mysql" {
  identifier              = "terraform-mysql"
  allocated_storage       = 20
  engine                  = "mysql"
  engine_version          = "8.0"
  instance_class          = "db.t3.micro"
  username                = "admin"
  password                = "SuperSecret123!"  # 실사용 시 환경변수로 관리 권장
  skip_final_snapshot     = true
  db_subnet_group_name    = aws_db_subnet_group.rds_subnet_group.name
  vpc_security_group_ids  = [aws_security_group.web_sg.id]
  publicly_accessible     = true

  tags = {
    Name = "terraform-mysql"
  }
}

 

  • 실행순서 
terraform init      # 초기화
terraform plan      # 배포 미리 보기
terraform apply     # 실제 배포
terraform destroy   # 전부 삭제

 

  • 폴더 예시

[Spring 프로젝트]
├── build.gradle
├── src/
├── terraform/
│   ├── provider.tf
│   ├── vpc.tf
│   ├── ec2.tf
│   ├── rds.tf
│   └── outputs.tf

 

cd terraform/
terraform init
terraform apply

 

안 그래도 AWS 콘솔 창에서 왔다 갔다 하는 것도 귀찮기도 하고 삭제 시에 이것저것 생각해 봐야 하는 것도 귀찮았는데
쓸 일이 있으면 한 번 써봐야겠다는 생각이 들었다.
또한 IntelliJ에서 플러그인으로 설치를 하면 문법 하이라이팅이, 자동완성, 오류 체크, 포맷팅도 된다니 굉장히 편리한 듯!
이 패턴을 IaC(Infrastructure as Code)라고 하는데 이것도 추후에 좀 더 자세히 알아보면 좋을 것 같다.