Terrafrom ( tf )

djEjgrpgksmsrjwl·2025년 1월 2일

SK shieldus Rookies 23기

목록 보기
15/24

[4일차]
테라폼
└> 프로바이더 , 데이터 , 리소스

1. 테라폼 설치

데비안계열의 리눅스의 경우 apt install terraform -y로 설치 가능 ( 또는 공식홈 설치방법 참고 )

https://developer.hashicorp.com/terraform/install

윈도우는 다운로드 후 환경변수 설정 ( 어느경로에서도 사용할 수 있게 하기 위함 )

2. VSC 테라폼 기능 확장

확장기능 을 통해 테라폼 설치

오픈폴더를 통해 프로젝트 폴더 지정, 새파일 terra.tf 생성

3. AWS 클라우드 기능 확인 ( 구축하기 위해 필요한 정보 )

IAM, EC2, VPC(Subnet, IGW, CIDR, ENI, SG ...)

└ 구축에 필요한 정보 AWS 사이트 등을 통해 수집

  • IAM : 정책이나, 사용자 계정 관리, 액세스키, 보안관리(로그인, 비밀번호 변경주기 등) 등
    -> 클라우드 트레일에 로그 저장됨
    => 액세스 키를 생성해야함(프로바이더 연결지정)

  • EC2 : 서버( 서버이름(필수아님), OS, 서버 성능, 키페어, 볼륨, EIP, 퍼블릿, SG )
    서버이름 : rookies
    OS : AMI ID : ami-049788618f07e189d
    성능 : t2.micro
    키페어 : ~~.pem => 서버 구축 후 ssh로 접속하기 위함
    VPC : EIP(퍼블릭모드시 기본할당), 퍼블릭모드, SG(기본으로 잡아주며 추가 편집가능), Subnet

  • VPC : 가상 프라이빗 클라우드 ( 태그, CIDR 블록 ) => id(고유식별번호)로 관리됨
    서브넷 : 태그, 가용영역, CIDR블록, VPC ID( => VPC 안에 존재함)
    라우팅테이블 : 이름(태그), VPC, CIDR, IGW
    외부와 -> VPC간의
    VPC안에 서로 다른 네트워크 대역 : 서브넷 구간
    인터넷게이트웨이 : 이름(태그), attach VPC에 연결
    탄력적 IP ( EIP ) : 리전정보
    SG : 이름(태그), 설명, VPC, 인/아웃바운드 규칙 설정

    ENI (Elastic Network Interface) : 가상 네트워크 인터페이스 (EC2 인스턴스에서 기본적으로 하나의 ENI가 자동으로 생성되지만, 필요에 따라 추가 ENI를 생성하고 인스턴스에 연결할 수 있습니다.) => 프라이빗 IP를 할당 >> 서브넷, SG, IP
    └ EIP가 할당됨

*구문 작성 전 EC2에서 키페어 생성

4. 테라폼 파일 구문 이해

코드 작성을 위한 참고 사이트 - https://registry.terraform.io/providers/hashicorp/aws/latest/docs

vscode 작성 ( 코드 오타 및 작성 용이 )

provider "aws" {
  region     = "ap-northeast-2"
  access_key = "AKIA***************"
  secret_key = "W5Yv4******************************"
} 

└> IaC를 통해 내가 인프라를 구축할 환경 및 접속 정보 지정

입력 형식에 따른 구문 작성방법

  • 코드로 가져오는 방법
  • 변수로 가져오는 방법 - " "로 묶어줘야함

터미널에 입력하는 terraform 기본 명령 구문

  • terraform.exe init // tf파일에 대한 문제점 체크 ( 배포전 작성한 구문의 오류 확인, 접속테스트 => 환경 초기화 작업 )
  • terraform plan // 내가 작성한 테라폼 구문에 설정된 변수 내용을 출력
  • terraform apply // 배포 및 구축 작업 수행
  • terraform destroy // 리소스 삭제

테라폼 구문 작성 시 큰틀에서 작은틀로 작성하는게 좋음. ( + 헷갈리지 않기 위함도 있음 )
└ EC2와 VPC중 누가 더 큰틀(부모)로 봐야할까? 또는 동일 선상에서 놓고 봐야할까?
=> VPC가 더 큰틀이다. 인스턴스를 가능하면 가장 늦게 선언하는게 좋다.

구문 순서
VPC
Subnet
IGW
Route ┬-- 이렇게 한세트다.
RTA---┘
SG
eni
eip
인스턴스

provider "aws" {
  region     = "ap-northeast-2"
  access_key = "AKIAQ***************"
  secret_key = "W5Yv4*********************************"
}

resource "aws_vpc" "rookies021_terra_vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "rookies021_terra_vpc"
  }
}

resource "aws_subnet" "rookies021_terra_subnet" {
  vpc_id            = aws_vpc.rookies021_terra_vpc.id
  cidr_block        = "10.0.10.0/24"   # 10.0.10.4 ~ 252
  availability_zone = "ap-northeast-2a"  ## 생략가능

  tags = {
    Name = "rookies021_terra_subnet"
  }
}

resource "aws_internet_gateway" "rookies021-terra-gw" {
  vpc_id = aws_vpc.rookies021_terra_vpc.id

  tags = {
    Name = "rookies021-terra-gw"
  }
}

resource "aws_route_table" "rookies021-terra-rt" {
  vpc_id = aws_vpc.rookies021_terra_vpc.id

  route {
    cidr_block = "0.0.0.0/0"  # 통신 허용 대역 , 로컬 (지정VPC) 대역은 기본으로 들어가진다.
    gateway_id = aws_internet_gateway.rookies021-terra-gw.id
  }

  tags = {
    Name = "rookies021-terra-rt"
  }
}

resource "aws_route_table_association" "rookies021-terra-rta" {
  subnet_id      = aws_subnet.rookies021_terra_subnet.id
  route_table_id = aws_route_table.rookies021-terra-rt.id
}

resource "aws_security_group" "rookies021-terra-sg" {
  name        = "rookies021-terra-sg"
  description = "SSH(22),HTTP(80),HTTPS(443) Allow!!"
  vpc_id      = aws_vpc.rookies021_terra_vpc.id

  tags = {
    Name = "rookies021-terra-sg"
  }
    ingress {
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
    ingress {
    from_port        = 80
    to_port          = 80
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
    ingress {
    from_port        = 443
    to_port          = 443
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
  }
    egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"   # -1 = all protocol
    cidr_blocks      = ["0.0.0.0/0"]
  }
}

resource "aws_network_interface" "rookies021-terra-eni" {
  subnet_id       = aws_subnet.rookies021_terra_subnet.id
  private_ips     = ["10.0.10.50"]
  security_groups = [aws_security_group.rookies021-terra-sg.id]

}

resource "aws_eip" "rookies021-terra-eip" {
  domain                    = "vpc"
  network_interface         = aws_network_interface.rookies021-terra-eni.id
  associate_with_private_ip = "10.0.10.50"
  depends_on = [aws_instance.rookies021-terra-web2]
}

resource "aws_instance" "rookies021-terra-web2" {
  ami           = "ami-049788618f07e189d"
  instance_type = "t2.micro"

  network_interface {
    network_interface_id = aws_network_interface.rookies021-terra-eni.id
    device_index         = 0
  }

  tags = {
    Name = "rookies021-terra-web2"
  }
}

5. 웹서버 배포 작업

인스턴스가 배포되면서, 자동으로 apache2(httpd)서버가 설치되고 실행되도록 설정

user_data = <<-EOF		# 언어 사용한다는것임
            #!/bin/bash
            sudo yum install httpd -y	# 아마존 리눅스는 래드햇계열로 apt가 안된다. yum을 사용해야함
            sudo systemctl start httpd	
            sudo bash -c 'echo "Terraform HTML TEST!!!!!" > /var/www/html/index.html'
            EOF
  • 명령어 실행이 안된경우
    1) 설치가 늦는 경우
    2) 출력 파일 지정하지 않은 경우.
    3) var/www/html 이 기본 httpd디렉토리, 그러나 비어 있음

ps -ef : 서비스 목록 볼수 있음
ss -tlunp : 활성화된 목록을 리스닝 상태로 봄

6. state 내용 확인 => 배포된 것에 대한 내용을 긁어오는 것임.

시스템이 커질 수록 검증 또는 오류과정에서 용이하게 사용함

terraform state list => 사용하고 있는 변수 모두 출력됨
terraform state show [확인하고자 하는 변수값] => 변수값에 들어가있는 정보 알려줌

  1. 삭제
profile
sunseonghwan

0개의 댓글