Overview
2023.04.04 - [Hashicorp] - 1. Terraform 기초 : 설치 및 .tf 파일 설명
2023.04.06 - [Hashicorp] - 2. Terraform 변수 사용법(use-variable)
오늘은 테라폼의 다양한 변수들에 대해 공부해보려고 한다.
1. variable
변수 블록은 Terraform 모듈 또는 구성에 대한 입력 변수를 정의하는 데 사용된다. 이러한 변수를 사용하면 구성을 매개변수화하여 더 유연하고 재사용할 수 있다. 사용자는 Terraform 명령을 실행할 때 이러한 변수에 대한 값을 전달하거나 환경 변수 또는 .tfvars 파일을 사용하여 설정할 수 있다.
예제코드
variable "region" {
type = string
description = "AWS region for the resources"
default = "us-west-2"
}
variable "instance_type" {
type = string
description = "EC2 instance type"
default = "t2.micro"
}
- 주의할점 : variable는 변수를 정의해준것이다. 위에 말한것처럼 xxx.tvars 파일에 해당 변수에 입력값을 넣어줘야 한다. 넣어주지 않으면 default값이 자동으로 들어간다.
예제코드2(Validation)
Terraform CLI v0.13.0에서 도입되었다.
variable "image_id" {
type = string
description = "The id of the machine image (AMI) to use for the server."
validation {
condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
}
}
- validation해당 블록 내에 블록을 추가하여 특정 변수에 대한 사용자 지정 유효성 검사 규칙을 지정할 수 있다
- AMI ID의 구문이 올바른지 확인한다.
- condition : 유효성 검사를 통과하려면 true로 평가되어야 하는 부울 표현식이다. 다음 두 가지를 확인한다.
- var.image_id의 길이는 4보다 커야 한다. 이렇게 하면 제공된 값의 길이가 최소가 된다.
- var.image_id의 처음 4자는 "ami-"와 같아야 합니다. 이렇게 하면 제공된 값이 AMI ID에 대한 올바른 접두사를 갖게 된다.
- error_message: condition이 false로 평가되면 이 오류 메시지가 사용자에게 표시된다.
- 이 경우 메시지는 image_id 값이 "ami-"로 시작하는 유효한 AMI ID여야 함을 사용자에게 알린다.
2. local
로컬 값은 Terraform 구성 내에서 재사용 가능한 표현식을 정의하는 데 사용된다. 복잡한 표현식을 단순화하거나 중간 결과를 저장하거나 구성을 더 읽기 쉽게 만드는 데 유용하다. 간단하게 설명하자면, 지역변수와 같은 역할이다. 해당 파일에서 정의했으면 해당파일에서만 사용할 수 있다.
예제코드
locals {
common_tags = {
Terraform = "true"
Environment = var.environment
}
}
resource "aws_instance" "example" {
ami = "ami-0c555b51c2a1d4e55"
instance_type = var.instance_type
tags = merge(
local.common_tags,
{
Name = "example-instance"
},
)
}
예제코드2
AWS의 모든 리소스에 terraform=true 태그를 붙이는 모듈 만들기 (local 함수 사용)
- 모듈 파일을 저장할 'tags_module'이라는 폴더를 만든다.
- tags_module 폴더 안에 다음 내용으로 main.tf 파일을 만든다.
# tags_module/main.tf
variable "additional_tags" {
type = map(string)
description = "Additional tags to be added to the common tags"
default = {}
}
locals {
common_tags = {
Terraform = "true"
}
}
output "tags" {
value = merge(local.common_tags, var.additional_tags)
}
- additional_tags를 가져와 terraform=true 태그를 포함하는 common_tags 로컬 값과 병합한다.
- 병합된 태그는 'tags'라는 출력 변수로 노출된다.
- type = map(string)
- 변수는 키와 값이 모두 문자열인 맵(키-값 쌍의 모음)이어야 함을 지정한다.
- 이 값을 정의함으로써 Terraform은 이 변수에 대해 제공된 입력 값이 문자열 키와 값이 있는 map임을 확인한다.
그리고 기본 Terraform 구성에서 tags 모듈을 호출하고 출력을 사용하여 AWS 리소스에 태그를 적용할 수 있다.
# main.tf
provider "aws" {
region = var.region
profile = var.aws_profile
}
module "tags" {
source = "../tags_module"
additional_tags = {
Environment = var.environment
}
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.my_public_ip]
}
tags = module.tags.tags
}
resource "aws_instance" "ec2" {
ami = "ami-03221589fd7c8f183" # This is an example Amazon Linux 2 AMI ID; replace with the appropriate AMI ID for your region
instance_type = var.instance_type
key_name = var.key_pair_name
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
tags = module.tags.tags
}
- Environment 태그가 모듈에 전달되고 모듈의 출력이 aws_security_group 및 aws_instance 리소스 모두에 대한 tags 속성으로 사용된다.
3. data
Terraform의 데이터 소스를 사용하면 외부 소스(예: API 또는 원격 파일) 또는 Terraform 외부에서 관리되는 기존 인프라에서 정보를 가져올 수 있다. 리소스를 직접 관리하지 않고도 구성에서 사용할 데이터를 수집할 수 있다.
예제코드
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
resource "aws_instance" "example" {
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
tags = merge(
local.common_tags,
{
Name = "example-instance"
},
)
}
- data "aws_ami" "amazon_linux": 이 데이터 블록은 최신 Amazon Linux 2 AMI에 대한 Amazon 머신 이미지(AMI) ID를 가져오는 데 사용된다.
- 이름 패턴 amzn2-ami-hvm-*-x86_64-gp2를 기반으로 사용 가능한 AMI를 필터링하고 AMI의 소유자는 "amazon"(공식 Amazon Linux AMI임을 나타냄)으로 설정된다.
- most_recent 속성은 true로 설정되어 지정된 패턴과 일치하는 사용 가능한 최신 AMI를 가져온다.
- resource "aws_instance" "example": 이 리소스 블록은 data "aws_ami" "amazon_linux" 블록에서 가져온 AMI ID를 사용하여 EC2 인스턴스를 생성하는 데 사용된다.
- instance_type은 변수(var.instance_type)를 통해 제공되며 사용자가 Terraform 구성을 적용할 때 인스턴스 유형을 사용자 정의할 수 있다.
예제코드2 (Ubuntu 20.04)
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical, the official owner of Ubuntu AMIs
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
resource "aws_instance" "example" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
tags = merge(
local.common_tags,
{
Name = "example-instance"
},
)
}
- owners는 aws_ami 데이터 소스 블록의 필드이다.
- 'owners' 필드는 AMI 소유자의 계정 ID를 기반으로 AMI를 필터링하는 데 사용된다.
- 'owners' 필드에 계정 ID를 지정하면 해당 계정이 소유한 AMI만 가져올 수 있다.
- 이 특정 코드 블록에서 owners 필드에는 ["099720109477"] 값이 있으며 이는 AWS에서 Ubuntu AMI의 공식 소유자이자 유지 관리자인 Canonical의 계정 ID이다.
- 'owners' 필드를 Canonical의 계정 ID로 설정하면 데이터 소스가 EC2 인스턴스 생성을 위해 최신 공식 Ubuntu 20.04(Focal Fossa) AMI만 가져오도록 할 수 있다.
아래의 소스에서 ami 부분만 변경해서 실행한 결과입니다.
main.tf 파일만 예시로 보여드립니다. 나머지 파일들도 전부 생성해줘야 합니다. 아래의 github에 있습니다.
https://github.com/somaz94/terraform-study-aws/tree/main/use-data-block
somaz@AD01769994:~/PrivateWork/terraform-study/use-data-block$ cat main.tf
provider "aws" {
region = var.region
profile = var.aws_profile
default_tags {
tags = {
Terraform = var.terraform
Environment = var.environment
}
}
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.my_public_ip]
}
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical, the official owner of Ubuntu AMIs
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
resource "aws_instance" "ec2" {
ami = data.aws_ami.ubuntu.id # This is an example Amazon Linux 2 AMI ID; replace with the appropriate AMI ID for your region
instance_type = var.instance_type
key_name = var.key_pair_name
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
}
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform init
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform fmt
main.tf
terraform.tfvars
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform validate
Success! The configuration is valid.
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform plan
data.aws_ami.ubuntu: Reading...
data.aws_ami.ubuntu: Read complete after 0s [id=ami-0c6e5afdd23291f73]
...
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform apply
data.aws_ami.ubuntu: Reading...
aws_security_group.allow_ssh: Refreshing state... [id=sg-02170f94bd5b24448]
data.aws_ami.ubuntu: Read complete after 0s [id=ami-0c6e5afdd23291f73]
...
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform state list
data.aws_ami.ubuntu
aws_instance.ec2
aws_security_group.allow_ssh
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ ssh -i ~/.ssh/somazkey.pem ubuntu@3.37.129.246
ubuntu@ip-172-31-34-2:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal
somaz@AD01769994:~/PrivateWork/terraform-study/use-variable$ terraform destroy
data.aws_ami.ubuntu: Reading...
aws_security_group.allow_ssh: Refreshing state... [id=sg-02170f94bd5b24448]
data.aws_ami.ubuntu: Read complete after 0s [id=ami-0c6e5afdd23291f73]
aws_instance.ec2: Refreshing state... [id=i-06123bdaa7b4a8854]
- 리소스를 삭제해줍니다.
Reference
locals
outputs
variables
Input Variables
Data Sources
'IaC > Infrastructure Provisioning' 카테고리의 다른 글
5. Terraform의 다양한 Expression (0) | 2023.04.13 |
---|---|
4. Terraform의 다양한 Function(함수) (0) | 2023.04.11 |
2. Terraform 변수 사용법(use-variable) - AWS (0) | 2023.04.05 |
1. Terraform 기초 : 설치 및 .tf 파일 설명 (0) | 2023.04.04 |
Packer란? (0) | 2022.09.05 |