IaC(Infrastructure as Code)

AWS + Terraform

cwchoiit 2024. 3. 5. 15:10
728x90
반응형
SMALL
728x90
SMALL

이번엔 AWS Provider를 사용해서 Terraform을 이용해보자. 

 

AWS Provider

다음 링크는 AWS Provider 관련 링크이다.

 

Terraform Registry

 

registry.terraform.io

 

이 링크에서 우측 상단 "Documentation" 버튼을 클릭하면 어떻게 provider를 적어 넣을지 보여준다.

 

한번 우리가 기존에 만들었던 main.tf 파일에 다음 코드를 추가해보자.

provider "aws" {
	region = "ap-northeast-2"
}

 

그리고 그 다음에 위 예제대로 다음 코드를 추가해보자.

resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

 

이 작업을 수행하기 앞서 AWS CLI가 있어야 하고 AWS CLI Configure가 진행된 상태여야 한다.

 

 

이 상태에서 tf apply를 입력하면 다음과 같이 에러가 나온다.

 

이는 무슨 에러냐면, 새로운 Provider인 AWS를 사용하기로 했으면 tf init 명령어를 다시 실행해야 한다는 얘기이다. 그래서 다시 tf init 명령어를 실행해보자. 명령어를 실행하면 AWS Provider와 관련된 plugin이 설치되고 잘 진행된다.

 

이제 plan 명령어를 한번 실행해보자.

위 실행 결과로 VPC 관련 무언가가 생성된다고 나온다. AWS에 VPC를 만들어내는 과정인듯하다. apply 명령어를 실행해보자.

실행이 정상적으로 끝나면 다음과 같이 AWS Console에서 만들어진 VPC를 확인할 수 있다.

 

이 VPC를 만들 때 이것 역시 Output을 설정해서 결과 후 내용을 확인할 수도 있다. 다음 문장을 추가하고 다시 apply 해보자.

output "aws_vpc" {
	value = aws_vpc.vpc
}

 

value = aws_vpc.vpc는 우리가 resource로 정의한 이 부분이다.

resource "aws_vpc" "vpc" {
	cidr_block = "10.0.0.0/16"
}

 

이러고 다시 apply를 하면 이러한 output이 나온다. VPC에 대한 ARN, CIDR Block, Id 등 정보가 보여진다.

 

여기 보면 여러 내용이 나오는 것을 알 수 있는데 이 말은 이렇게 VPC를 만들 때 이러한 데이터들 역시 같이 만들어 질 수 있다는 얘기가 된다. 그 중 하나인 "tags" 정보를 추가해보자.

resource "aws_vpc" "vpc" {
	cidr_block = "10.0.0.0/16"
	tags = {
		"Name" = "Terraform"
	}
}

 

apply를 다시 해보자.

 

이번엔 1개가 변경된다고 보여진다. 그 변경 사항은 "tags"다. 이렇게 어떤게 변경될지 어떻게 변경될지 다 보여준다. AWS Console로 가서 VPC를 확인해보면 다음과 같이 Name Tag가 변경된 모습을 확인할 수 있다.

 

하나 더 수정해보자. 이번엔 CIDR Block을 다음과 같이 10.123.0.0/16으로 변경해보자. 

resource "aws_vpc" "vpc" {
	cidr_block = "10.123.0.0/16"
	tags = {
		"Name" = "Terraform"
	}
}

 

이렇게 변경하고 apply를 하면 어떻게 될까? 그냥 CIDR Block만 변경될까? 다음 결과를 보자.

위 내용을 보면 1개가 추가되고 1개가 삭제된다고 나온다. 변경되는 게 아니라 기존에 있던 VPC를 삭제하고 새로운 VPC를 만들어 낸다는 뜻이다. 왜냐하면 CIDR 값은 AWS에서 변경 가능한 값이 아니다. 그렇기 때문에 변경하고자 한다면 새로 추가를 해야한다. 그리고 이 사실을 Terraform은 알고 있기 때문에 내가 10.0.0.0/16을 10.123.0.0/16으로 변경하면 기존에 있던 VPC를 삭제하고 새롭게 VPC를 만든다. 이 부분을 매우 조심해야한다. 그래서 Plan을 반드시 면밀하게 검토한 후 Apply를 해야한다.

 

 이번엔 AWS Provider에서도 Data Sources를 사용해보자. 문서에서 좌측 사이드바에 VPC (Virtual Private Cloud)를 찾고 거기서 Data Sources의 "aws_vpcs"를 찾아보자.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpcs

 

Terraform Registry

 

registry.terraform.io

 

이 Data Source는 VPC 목록을 가져오는 Data Source이다. 이를 main.tf 파일에 다음과 같이 추가해보자.

data "aws_vpcs" "vpcs" {}

output "vpcs" {
	value = data.aws_vpcs.vpcs
}

 

추가한 후 Apply 명령어 실행하면 다음과 같이 서울 지역의 VPC 2개를 가져오는 모습을 확인할 수 있다.

 

 

Destroy

마지막으로 지금까지 했던 작업에 대한 제거 명령을 실행해보자.

tf destroy

 

이 명령어를 실행하면 지금까지 작업했던 리소스들을 제거한다고 먼저 알려준다.

 

제거를 하기 위해 "yes"를 입력하면 모든 리소스가 제거되고 AWS Console에서 VPC가 삭제됐는지 확인 가능하다.

 

 

중간 점검

AWS Provider와 Terraform을 이용해서 AWS 리소스를 만들거나 수정하거나 삭제가 가능했다. 이제 문서를 참고하여 리소스나 인프라에 대한 구축을 코드로 진행하는 한 발을 띈 셈이다.

 

EC2 Instance와 Terraform

이번엔 EC2 인스턴스를 Terraform으로 설정해보자.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance

 

Terraform Registry

 

registry.terraform.io

위 링크에서 EC2 Instance에 대한 Terraform 코드 작성 예시를 볼 수 있다. 예시를 따라 main.tf 파일에 다음과 같이 작성해보자.

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "tfec2" {
  ami           = ami-097bf0ec147165215
  instance_type = "t2.micro"

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

 

AMI에서 다음 부분은 AMI의 ID이다. 

ami-097bf0ec147165215

 

이 ID는 다음 화면과 같이 알 수 있다.

 

원하는 AMI ID를 가져와서 위 코드처럼 작성한 후 "tf init", "tf apply"를 실행한다.

 

다음과 같은 구성이 새로 추가가 된다는 내용을 보여준다. 확인 후 "yes".

 

참고로, Default VPC가 없는 경우가 있을 수 있다. 나의 경우가 그렇다. 이런 경우에는 본인이 가진 VPC의 서브넷 정보도 넣어줘야 한다. (다음 코드 참고)

 

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "tfec2" {
  ami           = ami-097bf0ec147165215
  instance_type = "t2.micro"
  subnet_id = "subnet-xxx"

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

 

이렇게 작성하고 실행하면 다음과 같이 잘 만들어진다.

 

AWS Console에서 확인해보면 잘 만들어졌다.

 

다음은 이미지를 좀 더 효율적으로 가져오는 방법에 대해서 알아보자.

AMI Image를 Data Source를 통해서 가져오기

문서를 보면 다음과 같은 예시 코드가 있다.

여기에서 data 부분을 보자. ubuntu 이미지를 가져오는 Data Source이다. 

 

다음은 가장 최신 이미지를 가져오겠다는 문장이다.

most_recent = true

 

이름으로 AMI Image를 필터링 하는데, ubuntu-22.04로 된 모든 이미지를 가져온다는 필터 부분이다.

filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }

아래와 같은 이미지를 말한다고 보면 된다. 

 

이 부분은 Virtualization Type이 hvm인 이미지들을 가져온다는 필터다.

filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

아래와 같이 Virtualization이 hvm이다.

 

AMI Image의 Owner를 나타낸다. 저 숫자는 Canonical을 말한다. (Ubuntu 만든 회사) 

owners = ["099720109477"] # Canonical

 

 

그래서 그 중 가장 최신 이미지를 가져오는 Data Source인 것. 그래서 이 예시를 기반으로 만든 main.tf 파일은 다음과 같다.

# main.tf

  1 provider "aws" {
  2   region = "ap-northeast-2"
  3 }
  4
  5 data "aws_ami" "ubuntu" {
  6   most_recent = true
  7
  8   filter {
  9     name   = "name"
 10     values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
 11   }
 12
 13   filter {
 14     name   = "virtualization-type"
 15     values = ["hvm"]
 16   }
 17
 18   owners = ["099720109477"] # Canonical
 19 }
 20
 21 resource "aws_instance" "terraform-ec2" {
 22   ami           = data.aws_ami.ubuntu.id
 23   instance_type = "t2.micro"
 24   subnet_id = "subnet-xxx"
 25
 26   tags = {
 27     Name = "terraform-ec2"
 28   }
 29 }

 

이렇게 만든 후 init - apply를 해보자.

우리가 원하는대로 EC2 인스턴스가 잘 만들어진 것을 확인할 수 있다.

 

728x90
반응형
LIST