Terraform Local Values dan Output: Panduan Lengkap untuk Konfigurasi yang Efisien
Pendahuluan
Terraform adalah alat infrastruktur sebagai kode (IaC) yang populer, memungkinkan Anda untuk mendefinisikan dan menyediakan infrastruktur secara deklaratif. Dua fitur penting Terraform yang berkontribusi pada konfigurasi yang bersih, modular, dan mudah dikelola adalah local values dan output values. Artikel ini akan membahas secara mendalam tentang local values dan output values, menjelaskan cara kerjanya, kapan menggunakannya, dan memberikan contoh praktis untuk membantu Anda memaksimalkan pemanfaatannya.
Apa Itu Local Values di Terraform?
Local values dalam Terraform memungkinkan Anda menetapkan nilai ke variabel di dalam modul atau konfigurasi Anda. Nilai-nilai ini bersifat lokal untuk file tempat mereka didefinisikan dan tidak diekspos di luar modul. Local values sangat berguna untuk:
- Menghilangkan pengulangan: Anda dapat menghitung nilai yang sama beberapa kali dan menggunakan local value untuk menyimpan hasil perhitungan tersebut.
- Membuat kode lebih mudah dibaca: Dengan memberi nama yang deskriptif pada ekspresi kompleks, Anda meningkatkan keterbacaan dan pemahaman konfigurasi Anda.
- Menyederhanakan logika kondisional: Anda dapat menggunakan local values untuk menyimpan hasil ekspresi kondisional, sehingga konfigurasi Anda lebih ringkas dan mudah dikelola.
Sintaks Local Values
Local values didefinisikan di dalam blok locals
:
locals {
nama_local_value = ekspresi
}
nama_local_value
: Nama unik untuk local value Anda.ekspresi
: Ekspresi Terraform yang menghasilkan nilai yang ingin Anda tetapkan. Ini bisa berupa nilai statis, panggilan fungsi, referensi ke variabel, atau kombinasi dari semuanya.
Contoh Local Values
Berikut adalah beberapa contoh cara menggunakan local values:
Contoh 1: Menghitung Nama Sumber Daya
Anggaplah Anda ingin membuat beberapa sumber daya dengan nama yang didasarkan pada lingkungan tempat Anda menerapkan infrastruktur. Anda dapat menggunakan local values untuk menghitung nama-nama ini:
variable "environment" {
type = string
}
locals {
resource_prefix = "${var.environment}-app"
instance_name = "${local.resource_prefix}-instance"
database_name = "${local.resource_prefix}-db"
}
resource "aws_instance" "example" {
ami = "ami-0c55b5805c62a456e"
instance_type = "t2.micro"
tags = {
Name = local.instance_name
}
}
resource "aws_db_instance" "example" {
allocated_storage = 20
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = local.database_name
username = "admin"
password = "password"
skip_final_snapshot = true
}
Dalam contoh ini, local values resource_prefix
, instance_name
, dan database_name
dihitung berdasarkan variabel environment
. Hal ini memungkinkan Anda dengan mudah mengubah nama semua sumber daya dengan mengubah nilai variabel environment
.
Contoh 2: Menggunakan Fungsi untuk Manipulasi String
Terraform menyediakan banyak fungsi bawaan yang dapat digunakan dalam local values untuk memanipulasi string, angka, dan tipe data lainnya. Contoh:
locals {
region = "us-west-2"
availability_zones = tolist(["${local.region}a", "${local.region}b", "${local.region}c"])
subnet_cidr_blocks = cidrsubnet("10.0.0.0/16", 8, 0) // Ini akan hanya menghasilkan satu subnet, perlu diperbaiki untuk menghasilkan tiga subnet
}
resource "aws_subnet" "example" {
count = length(local.availability_zones)
availability_zone = local.availability_zones[count.index]
cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index) // Menghasilkan 3 subnet
vpc_id = "vpc-0abcdef1234567890"
tags = {
Name = "subnet-${count.index + 1}"
}
}
Dalam contoh ini, availability_zones
menggunakan tolist
untuk membuat daftar dari string, dan kemudian cidrsubnet
digunakan untuk membagi blok CIDR menjadi subnet yang lebih kecil berdasarkan index. count.index
digunakan untuk memberikan setiap subnet blok CIDR yang unik.
Contoh 3: Menggunakan Logika Kondisional
Anda dapat menggunakan operator kondisional dalam local values untuk menentukan nilai berdasarkan kondisi tertentu:
variable "enable_logging" {
type = bool
default = true
}
locals {
logging_bucket_name = var.enable_logging ? "logging-bucket" : null
}
resource "aws_s3_bucket" "logging" {
count = var.enable_logging ? 1 : 0
bucket = local.logging_bucket_name
acl = "private"
}
Dalam contoh ini, logging_bucket_name
hanya diatur jika variabel enable_logging
adalah true
. Ini memungkinkan Anda mengaktifkan atau menonaktifkan logging dengan mudah dengan mengubah nilai variabel.
Apa Itu Output Values di Terraform?
Output values dalam Terraform digunakan untuk mengekspos nilai dari konfigurasi Terraform Anda setelah penerapan selesai. Nilai-nilai ini dapat digunakan untuk:
- Menyediakan informasi tentang infrastruktur yang dibuat: Anda dapat mengekspos alamat IP, nama host, atau ID sumber daya.
- Menggunakan nilai dalam konfigurasi lain: Anda dapat menggunakan output dari satu konfigurasi sebagai input ke konfigurasi lain.
- Membuat infrastruktur lebih mudah digunakan: Dengan mengekspos informasi penting, Anda membuat infrastruktur lebih mudah digunakan oleh pengembang dan operator.
Sintaks Output Values
Output values didefinisikan di dalam blok output
:
output "nama_output" {
value = ekspresi
description = "Deskripsi output (opsional)"
sensitive = true | false (opsional)
}
nama_output
: Nama unik untuk output value Anda.value
: Ekspresi Terraform yang menghasilkan nilai yang ingin Anda ekspos.description
: Deskripsi opsional dari output value. Ini membantu orang lain memahami tujuan output.sensitive
: (Opsional) Menentukan apakah nilai output harus diperlakukan sebagai sensitif. Jika diatur ketrue
, nilai output akan disembunyikan dalam output Terraform dan tidak akan disimpan dalam status.
Contoh Output Values
Berikut adalah beberapa contoh cara menggunakan output values:
Contoh 1: Mengekspos Alamat IP Instansi EC2
Setelah Anda membuat instansi EC2, Anda mungkin ingin mengekspos alamat IP publiknya:
resource "aws_instance" "example" {
ami = "ami-0c55b5805c62a456e"
instance_type = "t2.micro"
}
output "public_ip" {
value = aws_instance.example.public_ip
description = "Alamat IP publik instansi EC2"
}
Setelah penerapan, Terraform akan menampilkan alamat IP publik instansi EC2 di output.
Contoh 2: Mengekspos ARN Bucket S3
Anda mungkin ingin mengekspos ARN (Amazon Resource Name) dari bucket S3 yang Anda buat:
resource "aws_s3_bucket" "example" {
bucket = "example-bucket"
acl = "private"
}
output "bucket_arn" {
value = aws_s3_bucket.example.arn
description = "ARN bucket S3"
}
Setelah penerapan, Terraform akan menampilkan ARN bucket S3 di output.
Contoh 3: Menggunakan sensitive = true
Jika Anda memiliki output yang berisi informasi sensitif seperti kata sandi atau kunci API, Anda harus mengatur sensitive = true
:
resource "random_password" "db_password" {
length = 16
special = true
override_special = "!@#$%^&*"
}
output "db_password" {
value = random_password.db_password.result
description = "Kata sandi database"
sensitive = true
}
Dengan mengatur sensitive = true
, nilai kata sandi tidak akan ditampilkan di output Terraform dan tidak akan disimpan dalam status dalam teks biasa. Namun, **perhatikan bahwa ini TIDAK mencegah nilai tersebut dicatat dalam log jika Anda memiliki fitur pencatatan yang aktif. Ini hanya melindungi nilai dalam konteks Terraform.**
Kapan Menggunakan Local Values vs. Output Values?
Penting untuk memahami perbedaan antara local values dan output values untuk menggunakannya secara efektif:
- Local Values: Gunakan local values untuk menghitung nilai yang digunakan secara internal dalam modul atau konfigurasi Anda. Local values bersifat lokal dan tidak diekspos di luar konfigurasi Anda.
- Output Values: Gunakan output values untuk mengekspos nilai dari konfigurasi Anda setelah penerapan selesai. Output values dapat digunakan untuk menyediakan informasi tentang infrastruktur yang dibuat atau digunakan sebagai input ke konfigurasi lain.
Praktik Terbaik untuk Menggunakan Local Values dan Output Values
Berikut adalah beberapa praktik terbaik untuk menggunakan local values dan output values:
- Beri nama local values dan output values dengan deskriptif: Ini membuat konfigurasi Anda lebih mudah dibaca dan dipahami.
- Gunakan local values untuk menghilangkan pengulangan dan menyederhanakan logika: Ini membuat konfigurasi Anda lebih ringkas dan mudah dikelola.
- Gunakan output values untuk mengekspos informasi penting tentang infrastruktur Anda: Ini membuat infrastruktur Anda lebih mudah digunakan oleh pengembang dan operator.
- Gunakan
sensitive = true
untuk output values yang berisi informasi sensitif: Ini melindungi informasi sensitif dari terekspos dalam output Terraform dan status. - Dokumentasikan local values dan output values: Tambahkan komentar untuk menjelaskan tujuan dan penggunaan setiap local value dan output value.
Contoh Kasus Penggunaan Lanjutan
1. Modul untuk Membuat Klaster Kubernetes (EKS)
Dalam skenario ini, kita akan membuat modul Terraform untuk membuat klaster Kubernetes (EKS) di AWS. Kita akan menggunakan local values untuk mendefinisikan nama-nama sumber daya secara dinamis dan output values untuk mengekspos informasi penting tentang klaster yang dibuat.
struktur folder modul:
modules/
eks/
main.tf
variables.tf
outputs.tf
modules/eks/variables.tf:
variable "cluster_name" {
type = string
description = "Nama klaster EKS"
}
variable "region" {
type = string
description = "Wilayah AWS"
default = "us-west-2"
}
modules/eks/main.tf:
locals {
vpc_name = "${var.cluster_name}-vpc"
subnet_name = "${var.cluster_name}-subnet"
}
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = local.vpc_name
}
}
# Subnet
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "${var.region}a"
tags = {
Name = local.subnet_name
}
}
# IAM role untuk klaster EKS
resource "aws_iam_role" "cluster" {
name = "${var.cluster_name}-cluster-role"
assume_role_policy = jsonencode({
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
}]
Version = "2012-10-17"
})
}
# Attaching a policy to the IAM Role
resource "aws_iam_role_policy_attachment" "cluster-AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.cluster.name
}
# Klaster EKS
resource "aws_eks_cluster" "example" {
name = var.cluster_name
role_arn = aws_iam_role.cluster.arn
vpc_config {
subnet_ids = [aws_subnet.public.id]
}
}
modules/eks/outputs.tf:
output "cluster_name" {
value = aws_eks_cluster.example.name
description = "Nama klaster EKS"
}
output "cluster_endpoint" {
value = aws_eks_cluster.example.endpoint
description = "Endpoint API server klaster EKS"
}
Cara menggunakan modul:
module "eks_cluster" {
source = "./modules/eks"
cluster_name = "my-eks-cluster"
region = "us-west-2"
}
output "eks_cluster_name" {
value = module.eks_cluster.cluster_name
}
output "eks_cluster_endpoint" {
value = module.eks_cluster.cluster_endpoint
}
Dalam contoh ini, local values digunakan untuk membuat nama-nama VPC dan Subnet secara dinamis. Output values digunakan untuk mengekspos nama dan endpoint klaster EKS, yang dapat digunakan oleh konfigurasi lain atau ditampilkan kepada pengguna.
2. Membuat Grup Keamanan Dinamis
Contoh ini menggunakan local values untuk mendefinisikan aturan keamanan berdasarkan variabel. Output values digunakan untuk mengekspos ID grup keamanan yang dibuat.
variable "ports" {
type = list(number)
default = [80, 443, 22]
}
locals {
common_tags = {
Owner = "Example"
Environment = "Dev"
}
ingress_rules = [
for port in var.ports : {
from_port = port
to_port = port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "Allow traffic on port ${port}"
}
]
}
resource "aws_security_group" "example" {
name = "example-sg"
description = "Example security group"
ingress {
for_each = { for idx, rule in local.ingress_rules : idx => rule }
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
description = each.value.description
}
tags = merge(
local.common_tags,
{
Name = "example-security-group"
}
)
}
output "security_group_id" {
value = aws_security_group.example.id
}
Local values membantu membuat aturan ingress dinamis berdasarkan variabel ports
. Hal ini membuat konfigurasi lebih ringkas dan mudah diubah. Output mengekspos ID grup keamanan, memungkinkan konfigurasi lain untuk mereferensikannya.
Tips Tambahan
- Modularitas: Gunakan local values dan output values untuk membuat modul Terraform yang modular dan dapat digunakan kembali.
- Keterbacaan: Gunakan local values untuk memecah ekspresi yang kompleks menjadi bagian-bagian yang lebih mudah dibaca.
- Keamanan: Selalu gunakan
sensitive = true
untuk output values yang berisi informasi sensitif. - Pengujian: Uji modul Terraform Anda secara menyeluruh untuk memastikan bahwa local values dan output values berfungsi sebagaimana mestinya.
Kesimpulan
Local values dan output values adalah fitur penting dari Terraform yang membantu Anda membuat konfigurasi yang bersih, modular, dan mudah dikelola. Dengan menggunakan local values untuk menghilangkan pengulangan dan menyederhanakan logika, dan menggunakan output values untuk mengekspos informasi penting, Anda dapat membuat infrastruktur sebagai kode yang lebih efektif dan mudah digunakan. Dengan memahami dan menerapkan praktik terbaik yang dibahas dalam artikel ini, Anda dapat memaksimalkan manfaat dari local values dan output values dalam proyek Terraform Anda.
“`