Bagi pengguna Amazon Web Services (AWS), mungkin selama ini hal yang umum dilakukan untuk akses ke Amazon EC2 instance adalah dengan melakukan SSH ke IP Public dari EC2. Atau jika EC2 tersebut tidak di-associate ke IP Public, maka hal yang umum dilakukan adalah SSH ke sebuah EC2 instance yang bertindak sebagai bastion host. Kemudian dari bastion host, kita lakukan ssh ke EC2 instance tujuan di private network.
Tapi tahukah anda bahwa ada cara lain untuk akses ke EC2 instance tanpa menggunakan SSH. Mungkin sebagian orang sudah paham dan menggunakan di keseharian. Namun saya ingin menyampaikan lagi mungkin ada yang belum familiar bahwa di untuk akses ke Amazon EC2 Instance kita dapat menggunakan AWS Session Manager.
Session Manager, seperti dikutip dari dokumentasi AWS AWS Systems Manager Session Manager, adalah fitur dari AWS yang memungkinkan kita untuk mengatur EC2 instance, on-premises isntance atau virtual machine (VM) melalui interactive browser based shell ataupun via AWS Command Line Interface (AWS CLI). Session manager memungkinkan manajemen instance yang lebih aman dan dapat di-audit tanpa harus membuka port, menggunakan bastion host ataupun menggunkan SSH key.
Berikut beberapa manfaat session manager dikutip dari dokumentasi di atas:
- Sentralisasi akses menggunakan IAM policy
- Tidak perlu tambahan membuka inbound port dan menggunakan bastion host atau SSH key
- Akses dapat dilakukan via web console dan AWS CLI
- Port forwarding
- Cross-platform support (Windows, Linux dan MacOS)
- Memungkinan log dan audit session
Pada artikel kali ini saya akan mencoba menjelaskan hal hal dasar apa saja yang dibutuhkan jika kita ingin menggunakan fitur AWS Session Manager. Pada contoh di artikel ini, saya akan membuat IAM user yang bertindak sebagai ssm-user di notebook/mac, kemudian saya juga buat IAM role yang bertindak sebagai EC2 IAM Role/IAM Instance Profile. IAM user dan IAM role tersebut memiliki policy atau privileged masing-masing. Untuk konfigurasi IAM tersebut, akan saya lakukan via Infrastructure as Code tool yaitu Terraform (Terraform Cloud) dan untuk konfigurasi EC2 tidak dijelaskan lebih detail di artikel ini. Jika berminat untuk mengtahui cara konfigurasi EC2 via Terraform, silahkan kunjungi blog post saya yang lain di link berikut Provision Amazon EC2 Menggunakan Terraform CLI. Jika digambarkan topologi nya kurang lebih seperti berikut:
Konfigurasi
Pada artikel ini, struktur direktori yang digunakan untuk konfigurasi IAM via terraform code sebagai berikut:
iam/
├─ main.tf
├─ policies.tf
├─ roles.tf
├─ users.tf
├─ variables.tf
├─ json-policies/
├─ ludes-ec2-admin.json
├─ ludes-ssm-user.json
-
Sebagai langkah awal, saya mulai dengan membuat 1 file dengan nama main.tf. Di file ini saya akan 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 yang ada di file variable.tf yang berikutnya akan saya jelaskan.
# Setup terraform cloud and workspace terraform { backend "remote" { hostname = "app.terraform.io" organization = "lanandra" workspaces { name = "iam" } } } # Setup terraform providers terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.57.0" } } required_version = ">= 1.0.6" } # Setup AWS provider provider "aws" { region = var.aws_region }
-
Langkah berikutnya yaitu dengan membuat variable di file variable.tf. Di file ini saya deklrasikan variable aws_region.
# Setup AWS Region variable "aws_region" { type = string description = "AWS Region" default = "ap-southeast-1" }
-
Selanjutnya saya membuat iam_user di file users.tf. Disini saya membuat 1 iam user dengan nama ludes-ssm-user.
# Configuration related to IAM users resource "aws_iam_user" "ludes_ssm_user" { name = "ludes-ssm-user" path = "/" force_destroy = true tags = { "Name" = "ludes-ssm-user" } }
-
Kemudian saya membuat EC2 IAM Role/IAM Instance Profile di file roles.tf. Di file ini saya mulai dengan membuat policy assume role untuk akses ke service EC2 namun dibuat dengan mengambil referensi dari data. Selanjutnya membuat iam role dengan nama ludes-ec2-admin yang mana assume role nya berasal dari data di atas yang sudah di conver ke json format. Dan yang terakhir adalah karena ingin iam role ini juga bertindak sebagai EC2 IAM Role/IAM Instance Profile, maka saya buat resource aws_iam_instance_profile dengan nama yang sama dan mengacu ke role ludes-ec2-admin.
# IAM Policy with assume role to EC2 data "aws_iam_policy_document" "ec2_assume_role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } } } # Configure IAM role resource "aws_iam_role" "ludes_ec2_admin" { name = "ludes-ec2-admin" path = "/" assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json } # Configure IAM instance profile resource "aws_iam_instance_profile" "ludes_ec2_admin" { name = "ludes-ec2-admin" role = aws_iam_role.ludes_ec2_admin.name }
-
Selanjutnya saya akan definisikan IAM policy yang digunakan. Untuk ludes-ssm-user, akan dibuat resource inline policy ke user tersebut dan policy file mengacu ke file /json-policies/ludes-ssm-user.json. Sedangkan EC2 IAM Role ludes-ec-admin, akan di-associate inline policy yang mengacu ke file /json-policies/ludes-ec2-admin.json
# Configuration related to IAM policies resource "aws_iam_user_policy" "ludes_ssm_user" { name = "ludes-ssm-user" user = aws_iam_user.ludes_ssm_user.name policy = file("./json-policies/ludes-ssm-user.json") } resource "aws_iam_role_policy" "ludes_ec2_admin" { name = "ludes-ec2-admin" role = aws_iam_role.ludes_ec2_admin.id policy = file("./json-policies/ludes-ec2-admin.json") }
-
Berikut detail dari tiap file json policy.
ludes-ssm-user.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssm:ResumeSession", "ssm:TerminateSession", "ssm:StartSession", "ssm:DescribeSessions", "ssm:GetConnectionStatus" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2:DescribeInstances" ], "Resource": "*" } ] }
ludes-ec2-admin.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssm:DescribeAssociation", "ssm:GetDeployablePatchSnapshotForInstance", "ssm:GetDocument", "ssm:DescribeDocument", "ssm:GetManifest", "ssm:GetParameter", "ssm:GetParameters", "ssm:ListAssociations", "ssm:ListInstanceAssociations", "ssm:PutInventory", "ssm:PutComplianceItems", "ssm:PutConfigurePackageResult", "ssm:UpdateAssociationStatus", "ssm:UpdateInstanceAssociationStatus", "ssm:UpdateInstanceInformation" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2messages:AcknowledgeMessage", "ec2messages:DeleteMessage", "ec2messages:FailMessage", "ec2messages:GetEndpoint", "ec2messages:GetMessages", "ec2messages:SendReply" ], "Resource": "*" } ] }
-
Selanjutnya adalah menjalankan terraform plan dan terraform apply via Terraform Cloud, namun di artikel ini tidak saya jabarkan lebih detail.
-
Setelah terraform apply sudah dilakukan dan resource berhasil terbentuk. Selanjutnya kita bisa memastikan via AWS Web Console. Berikut saya coba memastikan user ludes-ssm-user dan role ludes-ec2-admin sudah berhasil terbentuk.
-
Seperti yang sudah saya singgung di bagian awal artikel ini, saya sudah menyiapkan 1 buah EC2 instance yang akan dicoba diakses via Session Manager. Pertama yang saya lakukan adalah saya jalankan perintah aws ec2 describe-instances untuk mengetahui instance ID dan menggunakan ludes-ssm-user sebagai profile. Sebelumnya saya sudah melakukan konfigurasi aws configure –profile ludes-ssm-user di local mac untuk input AWS_ACCESS_KEY_ID dan AWS_SECRET_ACCESS_KEY yang digunakan profile/user tersebut.
aws ec2 describe-instances --filters Name=instance-state-name,Values=running \ --query 'Reservations[*].Instances[*].{Instance:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}' \ --profile ludes-ssm-user \ --output text
-
Ekspektasinya adalah command di atas akan menampilkan instance ID dari EC2 yang akan digunakan sebagai target session manager.
-
Kita juga memastikan via web console apakah instance ID tersebut sesuai.
-
Selanjutnya kita bisa mencoba melakukan session manager session ke ID EC2 instance tersebut.
Command yang digunakan contohnya seperti berikut:
aws ssm start-session --target [instance_id] --profile [aws_cli_profile]
-
Dari screenshot di atas, kita sudah dapat menyimpulkan bahwa session ke EC2 sudah berhasil dan melakukan command command linux terkait. Dan akses ke EC2 tanpa harus menggunakan SSH atau via bastion host.
Kesimpulan
Akhirnya kita sampai di penghujung artikel ini. Pada artikel ini kita sudah membahas apa itu AWS Session Manager, apa fungsi dan manfaatnya. Kita juga sudah membahas bahwa akses ke EC2 instance dapat dilakukan via Session Manager, tanpa perlu SSH key ataupun akses via bastion host.
Kita juga sudah membahas bagaimana cara konfigurasi dasar AWS Session Manager.
Sekian artikel kali ini. Jika ada saran, kritik atau masukan silahkan tinggalkan di kolom komentar.
Sekian dan terima kasih.