본문 바로가기

AWS

TerraForm vpc ,subnet ,ec2 구성

728x90

어제 전담멘토님하고 클라우드에 관련된 질문 뿐만 아니라 여러가지로 궁금사항에 대해 질문을 했다.
그러다가 우연히 cloudformation과 terraform에 대해 설명을 해주셨다.
 
Iac 란 무엇인가 ??
infrastructure as Code 라고 불리고, 테라폼에서는 하시코프 설정언어 HCL을 사용하여
클라우드 리소스를 선언할 수 있다.
 
쉽게 이야기하면 인프라를 사람이 읽을 수 있는 코드로 만들고 
이를 통해 버전 관리,공유 및 재사용이 가능하다라는 엄청난 장점이 존재한다.
 
클라우드 멘토링을 여태 10번넘게 들은 것 같다. 모든 멘토님들이 말씀하시길 aws cli을 사용할 줄 알아야한다.
콘솔에서 클릭클릭해서 생성하는것은 때로는 엄청 귀찮은 작업이다.
 
그래서 이번기회에 aws cloudFormation 과 terraform 중 어느것을 사용할까? 고민을 했다.
 
aws cloudformation 은 자체 서비스인 aws 단일 서비스 환경에서 사용할 때 사용한다고 한다.
반면 terraform 은 다중 클라우드 지원과 상태관리,코드 재사용에 더 강점이 있고, 팀이 여러 클라우드
제공업체를 사용하거나 더 복잡한 인프라스트럭처를 관리해야 할 때 유용하다고 한다.
 
좋아 그럼 좀 더 범위 폭이 넓은 terraform을 사용해보자! 
 

1. 테라폼 사용 환경을 구축하자! terraform 을 설치할 수 있는 ec2를 한대 구동 시켜보자

 

다음 처럼 이름을 임의로 생성한 후 
pem키 설정 및 vpc도 default vpc 를 사용하겠습니다!
 

2. aws cli 설정 및 configure

 

cd /tmp
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install
aws --version
aws configure

AWS CLI 를 실행 하기 위한 기본 명령어 업니다.
aws config 명령어 시 CLI 유저 계정이 필요하므로 없다면 만들어 줍니다.
 

3. CLI 유저 생성하기

CLI-USER 이름으로 Access key 옵션을 활성화 해 줍니다.
 
 
 

CLI 유저가 생성되며 Download .csv 로 액세스 키와 비밀번호를 저장 해 줍니다.

4. aws configure 등록

root@~~ aws configure

AWS Access Key ID [None]: YOURACCESSKEY

AWS Secret Access Key [None]: YOURSECRETKEY

Default region name [None]: ap-northeast-2

Default output format [None]: json

5.  테라폼 설치하기

cd ~
mkdir terra
cd terra
wget https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
unzip terraform_1.2.3_linux_amd64.zip
./terraform --version
cd ~
pwd
PATH=${PATH}:/home/ec2-user/terra
terraform --version

wget 명령어로 terraform v1.2.3 버전을 다운 받습니다.
PATH 명령어로 어디서든 terraform 명령어를 사용하도록 해주고 버전을 확인 해 봅니다.
 

mkdir aws && cd $_
vi provider.tf
provider "aws" {
  # access_key = "YOUR-ACCESS-KEY"
  # secret_key = "YOUR-SECRETK-KEY"
  region = "ap-northeast-2"
}

terraform init
terraform plan
terraform apply

기본설정으로 aws 파일에 provider.tf 파일을 만들어주고 기본 값을 설정해준다.
이미 aws 의 cli에 접속한 상태라서 엑세스키는 상관이 없다. 나머지 값들도 이미 설정되어 있으므로
terraform init / plan / apply 를 명령어로 한번 더 확인 해줍시다!
 
terraform init : 테라폼의 코드를 스캔하고 어느 공급자인지 확인 한 후 필요한 코드를 다운 받는다.
terraform plan: 테라폼 작업 수행전 기본 코드의 큰 오류값을 확인 해 줍니다.
terraform apply:테라폼의 구성파일을 실행합니다. plan명령어에서 잡지 못한 오류들을 발견 해 줍니다.
 
 
6. 테라폼으로 VPC 생성하기
 

# vi new-vpc.tf
data "aws_availability_zones" "available" {
  state = "available"
}
resource "aws_vpc" "new_vpc" {
  cidr_block  = "192.168.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support = true
  instance_tenancy = "default"

  tags = {
    Name = "NEW-VPC"
  }
}
resource "aws_subnet" "new_public_subnet_2a" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.0.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[0]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2A"
  }
}
resource "aws_subnet" "new_public_subnet_2b" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.16.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[1]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2B"
  }
}
resource "aws_subnet" "new_public_subnet_2c" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.32.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[2]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2C"
  }
}
resource "aws_subnet" "new_public_subnet_2d" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.48.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[3]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2D"
  }
}
resource "aws_internet_gateway" "new_igw" {
  vpc_id = aws_vpc.new_vpc.id
  tags = {
    Name = "NEW-IGW"
  }
}
resource "aws_route_table" "new_public_rtb" {
  vpc_id = aws_vpc.new_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.new_igw.id
  }
  tags = {
    Name = "NEW-PUBLIC-RTB"
  }
}
resource "aws_route_table_association" "new_public_subnet_2a_association" {
  subnet_id = aws_subnet.new_public_subnet_2a.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2b_association" {
  subnet_id = aws_subnet.new_public_subnet_2b.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2c_association" {
  subnet_id = aws_subnet.new_public_subnet_2c.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2d_association" {
  subnet_id = aws_subnet.new_public_subnet_2d.id
  route_table_id = aws_route_table.new_public_rtb.id
}

vpc 생성을 위해 new-vpc.tf 파일로 다음처럼 vpc생성에 필요한 구성요소들을 적어준다.
2a,2b,2c,2d 4개의 퍼블릭서비넷을 생성하고  192.168.0.0/16 으로 설정한 vpc를 생성한다.
internetgate way 를 설정하고 routing table을 통해 2a,2b,2c,2d에 접근할 수있는 권한을 설정한다.
 

terraform init
terraform plan
terraform apply

11개의 구성요소 추가완료
 

설정한대로 잘 만들어졌습니다.
 
7. 테라폼으로 EC2 생성하기
 

# vi terra-ec2.tf
resource "aws_instance" "example" {
  ami                    = "ami-0fd0765afb77bcca7"
  instance_type          = "t2.micro"
  subnet_id              = "${aws_subnet.new_public_subnet_2a.id}"
  vpc_security_group_ids = [aws_security_group.instance.id]
  key_name  = "TerraForm"
  user_data = <<-EOF
              #!/bin/bash
              yum install -y httpd
              systemctl enable --now httpd
              echo "Hello, Terraform" > /var/www/html/index.html
              EOF

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

resource "aws_security_group" "instance" {

  name = var.security_group_name
  vpc_id = "${aws_vpc.new_vpc.id}"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["내 아이피/32"]
  }
  ingress {
    from_port   = -1
    to_port     = -1
    protocol    = "icmp"
    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-sg"
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}

variable "aws_subnet_id" {
  description = "The ID of the AWS subnet"
  type        = string
  # aws_subnet_id 변수의 기본값을 비워둡니다. 기본값은 terraform.tfvars 파일에 정의한 값이 사용됩니다.
}

variable "aws_vpc_id" {
  description = "The ID of the AWS VPC"
  type        = string
  # aws_vpc_id 변수의 기본값을 비워둡니다. 기본값은 terraform.tfvars 파일에 정의한 값이 사용됩니다.
}

variable "key_name" {
  description = "The name of the EC2 Key Pair"
  type        = string
  # key_name 변수의 기본값을 비워둡니다. 기본값은 terraform.tfvars 파일에 정의한 값이 사용됩니다.
}


output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}

output "public_dns" {
  value       = aws_instance.example.public_dns
  description = "The Public dns of the Instance"
}

output "private_ip" {
  value       = aws_instance.example.private_ip
  description = "The Private_ip of the Instance"
}

${}로 표시되어있는 것은 환경변수로 처리한 것이다.
해당 파일이 실행될 때 환경변수파일을 참고하기 위해서는
 
 terraform.tfvars파일을 생성해줘야한다.
docker 에서 .env에 환경변수를 설정하는 것과 비슷한 방식이다.

key_name = "pem키 이름 "
aws_subnet_id = "생성된 서브넷그룹 2a Id"
aws_vpc_id = "생성된 vpc id"

ssh 접속은 내 아이피에서만 접속하게 설정해놧습니다! 나의 아이피를 해당하는 곳에 넣어주시면 됩니다.
 
자 init-> plan -> apply 로 실행 !

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

private_ip = "내 사설아이피가 뜰겁니다"
public_dns = "dns주소가 뜹니다"
public_ip = "내 아이피가 뜰겁니다"

주소창에 퍼블릭 IP 로 접근하니 유저데이터에 넣었던 문구가 잘 나오고 있습니다.

 

 
테라폼으로 삭제해보자!
 
내가 여태 구성했던 vpc,subnet,route table,internet gateway,ec2 한번에 지우고싶다 ?
 

terraform destroy

terraform destory 명령어로 앞서 생성했던 자원들을 손쉽게 지울 수 있습니다.

 
이렇게 되면 내가 설정했던 aws 세팅을 전부 삭제되며 파일은 남아 있기때문에 
버전관리 뿐만아니라 관리하기도 더욱 편리하고 생성 및 삭제도 편리하게 할 수 있다.
 
 
프로비저닝:it인프라를 생성하고 설정하는 프로세스
 
 
 

728x90