Saat melakukan provisioning atau pembuatan resource Amazon Web Services (AWS) via Terraform, mungkin yang paling umum kita jumpai adalah dengan mereferensikan AWS Credentials yang umumnya terdiri dari AWS Access Key ID dan AWS Secret Access Key.
Pada blogpost kali ini saya akan mencoba menyampaikan salah satu alternatif dalam proses provision AWS resource via Terraform. Saya akan mereferensikan IAM assumed role pada saat provisioning.
Sebagai konteks dan sebelum memulai konfigurasi, berikut saya coba sampaikan skenario atau arsitektur yang saya gunakan dalam blogpost kali ini:
- Pada contoh kasus di blogpost ini, saya menggunakan Terraform dengan backend remote atau Terraform Cloud
- Jika umumnya di Terraform kita mereferensikan AWS Access Key ID dan AWS Secret Access Key secara langsung sebagai perantara untuk berinteraksi dengan AWS API, di contoh kali ini saya akan menggunakan IAM Role yang memiliki IAM policy terkait yang digunakan untuk provision AWS resource
- Namun memang di kasus seperti ini, kita tetap membutuhkan sebuah IAM user atau boleh saya sebut intermediary user yang bertugas sebagai perantara agar Terraform dapat berinteraksi dengan AWS API. Dan IAM user ini tetap memerlukan AWS Access Key ID dan AWS Secret Access Key, namun IAM user ini tidak memiliki privilege atau diasosiasi ke IAM policy sama sekali.
- Nantinya IAM role akan melakukan assume role ke IAM intermediary user sebelum dapat mengirim API call yang digunakan untuk melakukan provision AWS resource.
- Idenya adalah nantinya kita hanya perlu memperhatikan AWS keys yang digunakan oleh IAM intermediary user. Selebihnya yang perlu dilakukan adalah membuat IAM role dengan hak akses atau IAM policy yang diperlukan, kemudian IAM role tersebut melakukan assume role ke IAM intermediary user
Prasyarat
Seperti disebutkan di skenario di atas, untuk melalukan terraform provision via IAM assume role diperlukan beberapa IAM resource. Berikut beberapa resource yang diperlukan:
- IAM user sebagai intermediary user
- IAM role
- Asosiasi IAM policy ke IAM role
Di blogpost kali ini saya membuat IAM resource menggunakan terraform code. Berikut langkah-langkah yang diperlukan:
- Membuat IAM User yang akan digunakan sebagain intermediary user. IAM user ini akan diasosiasi ke dalam IAM group. IAM user dan IAM group akan dibuat menggunakan public terraform aws module iam. Berikut contoh code snippetnya:
#############
# IAM Users #
#############
module "tf_assume_user" {
source = "terraform-aws-modules/iam/aws//modules/iam-user"
version = "5.9.2"
name = "tf-assume-user"
force_destroy = true
create_iam_access_key = false
create_iam_user_login_profile = false
tags = {
Name = "tf-assume-user"
"my:environment" = "my-environment"
}
}
##############
# IAM Groups #
##############
module "tf_assume_group" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
version = "5.9.2"
name = "tf-assume-group"
attach_iam_self_management_policy = false
group_users = [
module.tf_assume_user.iam_user_name
]
custom_group_policy_arns = [
]
tags = {
Name = "tf-assume-group"
"my:environment" = "my-environment"
}
}
- Berikut tampilan contoh IAM group dan IAM user ketika dicek via AWS Web Console. Buat satu AWS credentials baru (AWS Access Key ID dan AWS Secret Access Key) yang akan digunakan IAM intermediary user.
- Buat IAM role yang akan menjadikan IAM intermediary user di atas sebagai trusted entity dan melakukan sts:AssumeRole. Kemudian di contoh blogpost kali ini saya akan mengasosiasikan IAM role tersebut dengan customer managed policy yang dapat digunakan untuk provision ke Amazon Lightsail. Policy yang digunakan untuk provision Lightsail cukup luas karena hanya untuk kebutuhan demo, untuk production environment pertimbangkan juga untuk membuat policy lebih ketat atau least privileged. IAM role dan IAM policy juga dibuat menggunakan public terraform module seperti disebutkan di atas. Berikut contoh code snippetnya:
#############
# IAM Roles #
#############
module "compute_admin_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
version = "5.11.1"
trusted_role_arns = [
"arn:aws:iam::12digitsawsid:user/tf-assume-user",
]
trusted_role_services = [
"lightsail.amazonaws.com"
]
create_role = true
role_name_prefix = "compute-admin-sbx"
role_requires_mfa = false
custom_role_policy_arns = [
module.lightsail_full_access.arn
]
}
################
# IAM Policies #
################
module "lightsail_full_access" {
source = "terraform-aws-modules/iam/aws//modules/iam-policy"
version = "5.11.1"
name = "lightsail-full-access"
path = "/"
description = "Provides full access to Amazon Lightsail"
policy = file("${path.module}/files/policies/lightsail/lightsail-full-access.json")
tags = {
Name = "lightsail-full-access"
"my:environment" = "my-environment"
}
}
- Berikut tampilan contoh IAM role ketika dicek via AWS Web Console.
Langkah Konfigurasi
Pada bagian ini saya akan menjelaskan langkah-langkah konfigurasi yang diperlukan ketika provision AWS resource. Seperti disebutkan di awal blogpost, saya menggunakan backend remote atau Terraform Cloud, jadi saya akan jelaskan sedikit terkait konfigurasi yang diperlukan di Terraform Cloud. Dan pada blogpost kali ini saya akan mencontohkan provision Amazon Lightsail Instance.
- Pada workspace yang digunakan untuk provision AWS resource, di bagian variables saya akan mengasosiasikan AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY yang digunakan oleh IAM intermediary user. Saya mereferensikan variable tersebut menggunakan variable sets. Untuk konfigurasi variable sets tidak saya jelaskan lebih detail, silahkan kunjungi blog Hashicorp ini untuk mengetahui lebih lanjut.
- Berikutnya di Terraform Code, saya membuat file main.tf. Di file ini saya mendeklarasikan konfigurasi Terraform yang akan mengacu ke Terraform Cloud (app.terraform.io) sebagai backend. Dan mereferensikan nama organisasi dan workspace yang digunakan. Kemudian saya juga deklarasikan terraform provider yang digunakan yaitu hashisorp/aws dengan versi terkait. Di akhir saya deklarasikan region aws yang digunakan, mengacu ke variable aws_region dan IAM role arn, mengacu ke variable role_arn yang keduanya di deklarasikan di file variables.tf yang berikutnya akan saya jelaskan.
###########################
# Terraform Configuration #
###########################
terraform {
backend "remote" {
hostname = "app.terraform.io"
organization = "my-organization"
workspaces {
name = "my-workspace"
}
}
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.53.0"
}
}
required_version = ">= 1.3.0"
}
provider "aws" {
region = var.aws_region
assume_role {
role_arn = var.role_arn
}
}
- Selanjutnya mendefinisikan variable yang digunakan oleh Terraform di dalam file variables.tf.
variable "aws_region" {
type = string
description = "AWS Region"
default = "ap-southeast-1"
}
variable "role_arn" {
type = string
description = "IAM role ARN"
default = "arn:aws:iam::12digitsawsid:role/compute-admin-sbx"
}
variable "az" {
type = list(string)
description = "AWS Availability Zone"
default = ["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]
}
variable "key_pair_name" {
type = string
description = "Name of Lightsail key pair"
default = "my-key-pair"
}
- Berikutnya saya membuat contoh provision Amazon Lightsail Instance
######################
# Lightsail Instance #
######################
resource "aws_lightsail_instance" "my_instance" {
name = "my-instance"
availability_zone = var.az[0]
blueprint_id = "ubuntu_20_04"
bundle_id = "micro_2_0"
key_pair_name = var.key_pair_name
tags = {
"Name" = "my-instance"
"my:environment" = "my-environment"
"my:owner" = "my-owner"
}
}
resource "aws_lightsail_instance_public_ports" "my_instance_ports" {
instance_name = aws_lightsail_instance.my_instance.name
port_info {
protocol = "tcp"
from_port = 22
to_port = 22
}
port_info {
protocol = "tcp"
from_port = 443
to_port = 443
}
}
- Selanjutnya adalah melakukan commit dan push terraform code ke repository. Dan lakukan terraform plan dan terraform apply di Terraform Cloud workspace agar infrastructure dapat dibuat/provisioned. Untuk bagian ini hanya saya tampilkan simulasinya saja. Jika ingin melihat lebih detail bagaimana proses provisioning resource AWS via Terraform Cloud, silahkan lihat blogpost saya berikut ini.
- Setelah provisioning resource via Terraform Cloud sudah selesai. Langkah selanjutnya adalah memastikan resource berhasil terbentuk. Kita dapat menggunakan AWS web console untuk memastikannya. Saya akan masuk ke halaman service Lightsail dan memastikan instance sudah berhasil terbentuk.
Kesimpulan
Akhirnya kita sampai di penghujung artikel ini. Ada beberapa kesimpulan atau key takeaways yang ingin saya sampaikan:
- Selain menggunakan metode paling umum yaitu IAM user yang diberikan AWS Credentials (AWS Access Key ID dan AWS Secret Access Key) dan terasosiasi IAM policy, kita dapat melakukan provisioning AWS resource via Terraform menggunakan referensi IAM role (IAM assume role)
- Idenya adalah kita hanya perlu membuat IAM role dengan privilege yang dibutuhkan. Dan tidak perlu membuat banyak IAM user yang memerlukan pembuatan atau terasosiasi dengan AWS Credentials (AWS Access Key ID dan AWS Secret Access Key)
- Namun memang sampai ketika blogpost ini diterbitkan, saya menemukan masih ada keterbatasan dengan metode referensi IAM assume role, karena kita masih memerlukan IAM user yang bertugas sebagai perantara atau intermediary user dan user ini memerlukan AWS Credentials (AWS Access Key ID dan AWS Secret Access Key). Namun memang IAM user ini tidak terasosiasi dengan IAM policy apapun dan nantinya hanya IAM role yang memiliki policy
Silahka kunjungi GitHub repository saya untuk melihat contoh source code konfigurasi yang digunakan dalam artikel ini. Untuk contoh konfigurasi IAM resource yang diperlukan silahkan cek di directory iam dan untuk contoh pengaplikasian konfigurasi Terraform menggunakan assume role, silahkan cek di directory lightsail ini
Sekian artikel kali ini. Jika ada saran, kritik, atau masukan silahkan tinggalkan di kolom komentar.
Terima kasih!
Tinggalkan Balasan