본문 바로가기
Terraform

테라폼 채움 참조, 변수(variable), output 사용

by Nirah 2023. 2. 15.

 

초기 요구사항

  • AmazonEC2FullAccess 권한이 있는 IAM User
  • 기본 VPC (us-west-2)

 

 

목표

  • 특정 포트를 열어놓는 보안 그룹
  • EC2
    • 해당 포트로 접속하면 Hello, World를 보여주는 User Data
    • 위에서 설명한 보안 그룹 연결

 

목차

1. 채움 참조(interpolation)를 사용해 리소스 생성

2. 변수를 사용해 리소스 생성

3. 더 다양한 variable

 

 

 

테스트3 

이전 글에 더해서 조금 더 복잡하게 인프라를 설계해보자.

ec2나 vpc 달랑 만들고 테라폼이 편리하다고 느껴지지 않을테니,

이번에는 손으로 만들기는 살짝 귀찮아지는 수준을 만들어본다.

 

좀 더 자세한 옵션들은 아래의 공식 링크를 참고해서 추가하자.

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

 

  • EC2를 만든다.
  • SSH 키 페어를 만들어 EC2에 연결시켜 접속이 가능할 수 있게 한다.
  • 누구나 22번 SSH에 접속할 수 있도록 공개된 보안그룹 하나를 더 만들어 EC2에 붙인다.
  • RDS를 만든다. 실습이기 때문에 퍼블릭 액세스로 적은 사양으로 세팅한다.

 

ssh rsa 키는 방금 전 만든 키를 그대로 사용하겠다.

해당 ssh 키를 AWS에 올려 EC2를 접속하기 위한 SSH 키 페어로 등록할 것이다.

ssh-keygen -t rsa -f "C:\Users\sesac\.aws\.bbb"

 

previder.tf

리전을 정해주되, 보안상 var파일을 참조하도록 만든다.

 

 

instance.tf

누구나 ssh로 접속할 수 있도록 공개된 새로운 AWS 보안 그룹을 만들었다.

ingress는 인바운딩에 대한 정의를 하는 부분이다.

22번에 대한 모든 IP를 개방하고 태그도 추가해봤다.

 
resource "aws_security_group" "ssh" {
    name = "allow_ssh_all"
    description = "Allow SSH port 22 from all"
    ingress {
        from_port = 22
        to_port = 22
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    tags = {
        name = "allow_ssh_all"
    }
}

 

 

그 아래에 data 객체를 추가한다.

이는 필자가 이번 인프라에서 만들려는 것이 아닌 이미 AWS에 만들어져 있는 인프라 리소스를 불러오겠다는 의미이다.

이러한 리소스는 destroy 명령어를 사용하더라도 당연히 지워지지 않는다.

해당 리소스는 AWS default VPC의 default 보안 그룹을 의미한다.

data "aws_security_group" "default" {
    name = "default"
}

 

이번에는 EC2를 선언하는 코드다.

아까전의 EC2 인스턴스 코드에서 보안 그룹을 추가하는 "vpc_security_group_ids" 태그가 추가되었다.

위에서 선언한 보안 그룹 리소스들을 위와 같은 방식으로 추가해준다.

EC2를 생성할때 위에서 만든 보안그룹과 연결해주고 싶다면 참조해오면 된다.

 vpc_security_group_ids = [
        aws_security_group.ssh.id,
        data.aws_security_group.default.id

이부분인데, 위의 보안 그룹에선 내가 id를 지정하지 않았기 때문에 보안 그룹이 생성될때 어떤 id값을 가질 지 모른다.

그 변수값을 참조해주기 위해 채움참조를 쓰는 것이다.

 

vpc_security_group_ids = ["${aws_security_group.ssh.id}"]

이렇게 쓰는게 흔한 방식이다.

 

참고로 보안그룹 ID란 아래 세부정보에 있는 저 sg~식별자다.

resource "aws_instance" "webserverbbb2" {
    ami = "ami-0f1a5f5ada0e7da53"
    instance_type = "t2.micro"
    key_name = aws_key_pair.bbb.key_name
    vpc_security_group_ids = [
        aws_security_group.ssh.id,
        data.aws_security_group.default.id
    ]
    tags = {
        name = "raid1_web"
    }
}

 

 

+++참고로

또한 output 구문에서도 aaws_instance.webserverbbb2.public_ip 란을  참조를 사용해, 테라폼 실행 시 생성되는 EC2의 퍼블릭 IP를 출력할 수 있다.

output "public_ip" {
  value = aws_instance.webserverbbb2.public_ip
}

이런식으로 ip가 참조되어 출력된다.

 

 

 

 

RDS를 생성하는 리소스이다.

지금은 여기에 DB ID와 PASSWD가 노출되어있는데, 나중에 따로 ssh rsa key 페어를 처리한 방식 처럼

암호화 파일로 따로 두는 등 외부로 file을 걸어주면 된다.

resource "aws_db_instance" "web_db" {
  allocated_storage = 8
  engine = "mysql"
  // rds 대시보드에 뜨는 이름
  identifier = "raidone-rds"
  instance_class = "db.t2.micro"
  db_name = "raid1_web_db_name"
  username = "admin01"
  password = "It12345678"
  publicly_accessible = true
  skip_final_snapshot = true
  tags = {
    Name = "raid1_web_db"
  }
}

 

참고로 identifier는 반드시 소문자 및 하이픈-으로 구성돼야해서 raid1_rds라고 했다가 수정했다..

 

 

vars.tf

지금까지 var를 참조하도록 넘긴 데이터 값을 다 입력해준다.

variable "AWS_REGION" {
    default = "us-west-2"
}

variable "PATH_TO_PUBLIC_KEY" {
    default = "./bbb/.bbb.pub"
}

variable "PATH_TO_PRIVATE_KEY" {
    default = "./bbb/.bbb"
}

 

참고로 비밀번호는 최소 8자리 해달라고 에러가 떠서 수정했다.

 

 

결과 확인

EC2 인스턴스에 원하는 옵션이 다 확인 된다.

 

 

RDS도 잘 생성됐다.

 

 

 

 

 

 

테스트4

 

ami 카탈로그에서 적당히 아마존 리눅스2를 골랐는데, 접속이 안된다.. 

ami는 아래의 우분투것을 쓰도록 하자.

 

vars.tf

variable "AWS_REGION" {
    default = "us-east-1"
}

variable "PATH_TO_PUBLIC_KEY" {
    default = "./bbb/.bbb.pub"
}

variable "PATH_TO_PRIVATE_KEY" {
    default = "./bbb/.bbb"
}

 

instance.tf

 

resource "aws_instance" "webserverbbb3" {
    ami = "ami-40d28157"
    instance_type = "t2.micro"
    key_name = aws_key_pair.bbb.key_name
    vpc_security_group_ids = ["${aws_security_group.webinstance.id}"]
    
    user_data = <<-EOF
                #!/bin/bash
                echo "Hello, World" > index.html
                nohup busybox httpd -f -p 8080 &
                EOF
    tags = {
        name = "raid1_web"
    }
}

resource "aws_key_pair" "bbb" {
    key_name = "bbb"
    public_key =file(var.PATH_TO_PUBLIC_KEY)
}


resource "aws_security_group" "webinstance" {
    name = "allow_web"

    description = "Allow port 8080"
    ingress {
        from_port = 8080
        to_port = 8080
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    tags = {
        name = "allow_web"
    }
}

 

provider.tf

provider "aws" {
    region = var.AWS_REGION
}

 

output.tf

output "public_ip" {
  value = aws_instance.webserverbbb3.public_ip
}

 

 

이제 cmd창에서 적용해보자.

 

output 구문에서 aws_instance.example.public_ip 란 참조를 사용해,

테라폼 실행 시 생성되는 EC2의 퍼블릭 IP를 출력했다.

이를 보고 바로 curl을 치기 위해서다.

 

 

gui상에서도 잘 적용된지 확인해본다.

 

 

++ 추가 테스트

변수를 사용한 리소스 생성

 

위의 코드에서 8080이란 숫자가 반복이 된다

이를 변수로 처리해 8080이 아닌 다른 포트를 사용하게 될 때 바로바로 적용할 수 있도록 설정한다.

 

 

instance.tf

 

variable 구문이 추가되었다

server_port란 변수에 default값으로 8080을 설정해두어, 8080을 사용하던 user_data와 security group 구문들에 각각 적용할 수 있게 되었다

resource "aws_instance" "webserverbbb3" {
    ami = "ami-40d28157"
    instance_type = "t2.micro"
    key_name = aws_key_pair.bbb.key_name
    vpc_security_group_ids = ["${aws_security_group.webinstance.id}"]
    
    user_data = <<-EOF
                #!/bin/bash
                echo "raid1_aws_success!" > index.html
                nohup busybox httpd -f -p "${var.server_port}" &
                EOF
    tags = {
        name = "raid1_web"
    }
}

resource "aws_key_pair" "bbb" {
    key_name = "bbb"
    public_key =file(var.PATH_TO_PUBLIC_KEY)
}


resource "aws_security_group" "webinstance" {
    name = "allow_web"

    description = "Allow port 8080"
    ingress {
        from_port = var.server_port
        to_port = var.server_port
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    tags = {
        name = "allow_web"
    }
}

vars.tf

variable "AWS_REGION" {
    default = "us-east-1"
}

variable "PATH_TO_PUBLIC_KEY" {
    default = "./bbb/.bbb.pub"
}

variable "PATH_TO_PRIVATE_KEY" {
    default = "./bbb/.bbb"
}

variable "server_port" {
    description = "port the server will use for http requests"
    default = 8080
}

 

provider.tf와 output.tf는 테스트 4와 동일하다.

 

 

 

 

 

 default값도 아닌 테라폼 실행 때 마다 새로운 값을 입력받아 사용하고 싶다면, 아래와 같이 default 구문을 빼주자

variable "server_port" {
  description = "The port the server will use for HTTP requests"
}

이대로 terraform apply를 해주면

 

 

description 구문의 설명이 뜨면서 value를 입력하라고 한다

여기에 원하는 변수 값을 입력하면서 사용할 수 있다

또는, terraform apply -var server_port="8080" 과 같이 명령 줄 옵션으로 바로 변수를 지정하며 테라폼을 실행시킬수도 있다

 

 

 

 

 

 

 

reference

 

클라우드 수업과 별도로 공식문서, 테라폼 업엔러닝 책과 이 블로그들을 참조했다.

공식 튜토리얼

https://developer.hashicorp.com/terraform/language/syntax/configuration

 

Syntax - Configuration Language | Terraform | HashiCorp Developer

Key constructs of the native Terraform language syntax, including identifiers, arguments, blocks, and comments.

developer.hashicorp.com

 

 

https://honglab.tistory.com/114

 

[Terraform on AWS] 테라폼 입문 (in Window)

목차 1. Terraform이란? 2. 실습 환경 설명, terraform 설치 3. IAM User & ACCESS KEY 설정 4. 간단하게 EC2 배포해보기 (+멱등성 체험) 5. Terraform으로 프로비저닝한 리소스들 삭제 1. Terraform이란? 먼저 IaC(Infrastruc

honglab.tistory.com

 

https://blog.naver.com/shino1025/223013663808

 

[Terraform] 대충 쓴 테라폼 입문기

계속 써야지, 써야지 하고 미루다가 드디어 이 주제로 글을 쓰게 되었다. 최근에 다니고 있는 회사의 개발 ...

blog.naver.com

 

https://blog.naver.com/classmethodkr/222391116032

 

[Terraform] 테라폼으로 AWS 서비스 구축하기 2장. EC2 RDS S3 구축하기 (1)

시작하며 이전 글에선 테라폼의 설치와 버전 관리 툴인 tfswitch를 설치하고 사용법을 알아보았습니다. 이...

blog.naver.com