AWS App Runner: Solusi Menjalankan Aplikasi Berbasis Container Secara Mudah dan Serverless

tl;dr Cara provision dan menjalankan aplikasi berbasis container di AWS App Runner menggunakan Terraform

Menjalankan aplikasi berbasis container saat ini dapat dilakukan berbagai macam cara. Entah itu dengan menggunakan container orchestrator atau tanpa container orchestrator. Dengan menggunakan dan mengelola compute resource/server atau tanpa harus mengelola compute resource/server (serverless).

Amazon Web Services (AWS) menyediakan sebuah service bernama AWS App Runner. AWS App Runner merupakan salah satu solusi agar developer dapat menjalankan aplikasi berbasis container dengan mudah dan tanpa harus mengelola infrastruktur, server ataupun orchestrator. Selengkapnya terkait AWS App Runner dapat dilihat di dokumentasi berikut.

Pada blogpost kali ini, saya akan mendiskusikan cara menjalankan aplikasi berbasis container di AWS App Runner. Konfigurasi atau provision AWS resource menggunakan Terraform dengan backend remote (Terraform Cloud).

Skenario dan Topologi

Skenario dan topologi yang digunakan pada blog ini sebagai berikut:

topologi

  • Container image disimpan di repository yang ada di Amazon Elastic Container Registry (ECR)
  • AWS App Runner menjalankan deployment aplikasi dengan referensi container image yang sudah di push ke Amazon ECR

Konfigurasi pembuatan aplikasi, repository ECR dan push image tidak dijelaskan secara detail di blogpost ini. Blogpost ini hanya menitikberatkan konfigurasi AWS App Runner.

Konfigurasi

Pada artikel ini, struktur file yang digunakan oleh terraform code sebagai berikut:

apprunner/
├─ apprunner-use1/
│  ├─ main.tf
│  ├─ outputs.tf
│  ├─ service.tf
│  ├─ variables.tf
modules/
├─ apprunner/
│  ├─ ecr/
│  │  ├─ outputs.tf
│  │  ├─ service.tf
│  │  ├─ variables.tf

Resource service App Runner dibuat berdasarkan self managed module yang saya buat dimana di dalamnya dikonfigurasi beberapa parameter yang dijadikan template untuk membuat service App Runner dengan source dari container image yang ada di Amazon Elastic Container Registry (ECR). Referensi terrraform code berdasarkan dokumentasi terraform aws_apprunner_service.

Langkah Konfigurasi

  1. Konfigurasi saya mulai dengan membuat self managed module yang ada di directory modules/apprunner/ecr. File pertama yang saya diskusikan adalah modules/apprunner/ecr/variables.tf. Pada file ini saya definisikan variable-variable yang digunakan dalam module. Di antara variable-variable tersebut, beberapa saya definisikan default value untuk variable.

module-variables

variable "service_name" {
  type        = string
  description = "App Runner service name"
  default     = ""
}

variable "ecr_access_role_arn" {
  type        = string
  description = "ARN of ecr access role"
  default     = "arn:aws:iam::12digitsawsid:role/service-role/AppRunnerECRAccessRole"
}

variable "auto_deployment" {
  type        = bool
  description = "Whether auto deployment is enabled or disabled"
  default     = false
}

variable "container_port" {
  type        = string
  description = "Container port used by application"
  default     = ""
}

variable "container_image" {
  type        = string
  description = "URI of ECR container image"
  default     = ""
}

variable "ecr_repository_type" {
  description = "Whether ECR repository is private or public"
}

variable "cpu" {
  type        = number
  description = "CPU allocation"
}

variable "memory" {
  type        = number
  description = "Memory allocation"
}

variable "outgoing_network_traffic" {
  type        = string
  description = "Whether outgoing network traffic is public only or public+private via VPC"
  default     = "public"

  validation {
    condition     = contains(["public", "vpc"], var.outgoing_network_traffic)
    error_message = "Outgoing network traffic should be public or vpc."
  }
}

variable "vpc_connector_arn" {
  type        = string
  description = "ARN of VPC connector"
  default     = ""
}

variable "service_tags" {
  type        = map(string)
  description = "Set key value tags for App Runner service"
  default     = {}
}
  1. Berikutnya file yang akan didiskusikan adalah modules/apprunner/ecr/service.tf. Pada file ini, saya mendeklarasikan template konfigurasi service App Runner dengan source container image di ECR. Terraform Argument didefinisikan dengan acuan variable yang sudah didefinisikan di file modules/apprunner/ecr/variables.tf. Dan untuk network_configuration, argument didefinisikan dengan menggunakan metode dynamic argument sesuai dengan input yang dideklarasikan. Namun network_configuration memiliki default value "public".

module-service

# Create App Runner service with ECR as source reference
resource "aws_apprunner_service" "app_runner" {
  service_name = var.service_name
  tags         = var.service_tags

  source_configuration {
    authentication_configuration {
      access_role_arn = var.ecr_access_role_arn
    }
    auto_deployments_enabled = var.auto_deployment
    image_repository {
      image_configuration {
        port = var.container_port
      }
      image_identifier      = var.container_image
      image_repository_type = var.ecr_repository_type
    }
  }

  instance_configuration {
    cpu    = var.cpu
    memory = var.memory
  }

  # Condition check if outgoing network traffic is public only
  dynamic "network_configuration" {
    for_each = var.outgoing_network_traffic == "public" ? [1] : []

    content {
      egress_configuration {
        egress_type = "DEFAULT"
      }
    }
  }

  # Condition check if outgoing network traffic is public+private via VPC
  dynamic "network_configuration" {
    for_each = var.outgoing_network_traffic == "vpc" ? [1] : []

    content {
      egress_configuration {
        egress_type       = "VPC"
        vpc_connector_arn = var.vpc_connector_arn
      }
    }
  }
}
  1. Setelah itu di file modules/apprunner/ecr/outputs.tf. Saya deklarasikan output yang nantinya dapat dipanggil di root module.

module-output

# Set outputs
output "service_arn" {
  value = aws_apprunner_service.app_runner.arn
}
  1. Setelah child module untuk template service App Runner dengan source container image selesai dibuat, selanjutnya adalah konfigurasi App Runner root module. Saya mulai dengan menjelaskan file apprunner/apprunner-use1/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 yang ada di file apprunner/apprunner-use1/variables.tf yang berikutnya akan saya jelaskan.

root-main

# Setup terraform cloud and workspace
terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "lanandra"

    workspaces {
      name = "apprunner-us-east-1"
    }
  }
}

# Setup terraform providers
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.24.0"
    }
  }

  required_version = ">= 1.2.4"
}

# Setup AWS provider
provider "aws" {
  region = var.aws_region
}
  1. Selanjutnya adalah mendefinisikan variable yang digunakan oleh App Runner root module di file apprunner/apprunner-use1/variables.tf.

root-variables

variable "aws_region" {
  type        = string
  description = "AWS Region"
  default     = "us-east-1"
}

variable "ecr_repository_type" {
  type        = list(string)
  description = "Whether ECR repository is private or public"
  default     = ["ECR", "ECR_PUBLIC"]
}
  1. Berikutnya di file apprunner/apprunner-use1/service.tf, saya membuat service App Runner dengan referensi dari child module apprunner/ecr yang sudah saya buat sebelumnya. Di dalam konfigurasi App Runner root module ini saya deklarasikan nama service, URI ECR container image, container port, tipe ECR repository (index 0 untuk private), cpu, memory, network dan tags. Sebagai tambahan, saya siapkan konfigurasi custom domain yang akan digunakan oleh service App Runner.

root-service

# Create App Runner service from module
module "lanandra_bmi_calculator" {
  source = "../../modules/apprunner/ecr/"

  service_name             = "lanandra-bmi-calculator"
  container_image          = "12digitsawsid.dkr.ecr.us-east-1.amazonaws.com/lanandra-bmi-calculator:latest"
  container_port           = "5000"
  ecr_repository_type      = var.ecr_repository_type[0]
  cpu                      = 1024
  memory                   = 2048
  outgoing_network_traffic = "public"

  service_tags = {
    Name        = "lanandra-bmi-calculator"
    Environment = "Staging"
    Owner       = "Luthfi"
  }
}

resource "aws_apprunner_custom_domain_association" "lanandra_bmi_calculator" {
  domain_name = "lanandra-bmi-calculator.ludesdeveloper.com"
  service_arn = module.lanandra_bmi_calculator.service_arn
}
  1. Berikutnya di file apprunner/apprunner-use1/outputs.tf, saya mengeluarkan nilai output untuk keperluan konfigurasi dan validasi DNS record custom domain.

root-outputs

# Set outputs
output "certificate_validation_records" {
  value = aws_apprunner_custom_domain_association.lanandra_bmi_calculator.certificate_validation_records
}

output "dns_target" {
  value = aws_apprunner_custom_domain_association.lanandra_bmi_calculator.dns_target
}
  1. Berikutnya 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.

tfcloud-plan-apply

  1. Setelah provisioning resource via terraform sudah selesai. Langkah selanjutnya adalah memastikan resource-resource berhasil terbentuk. Kita dapat menggunakan AWS web console untuk memastikannya. Resource pertama yang akan kita verifikasi adalah service App Runner. Masuk ke halaman service App Runner, kemudian masuk ke menu Services. Pastikan resource service App Runner yang didefinisikan di terraform code berhasil terbentuk.

list-apprunner

  1. Selanjutnya masuk ke halaman detail dari service dengan meng-klik nama service di poin sebelumnya. Di bagian service overview, kita dapat memastikan ringkasan dari service seperti status service apakah sudah/sedang berjalan, nama domain default yang diberikan oleh service App Runner, ARN dari service dan juga source container image.

apprunner-overview

  1. Kemudian kita dapat juga memastikan detail konfigurasi yang didefinisikan di terraform code sudah sesuai atau belum dengan masuk ke tab Configuration.

apprunner-configuration-1

apprunner-configuration-2

apprunner-configuration-3

apprunner-configuration-4

apprunner-configuration-1

  1. Selanjutnya untuk konfigurasi custom domain App Runner, kita memerlukan beberapa informasi DNS record yang nantinya perlu ditambahkan di DNS server kita. Seperti dijelaskan sebelumnya, detail ini saya tampilkan di terraform output sehingga bisa dilihat di bagian output dari workspace Terraform Cloud.

tfcloud-outputs

  1. Atau cara lainnya adalah dengan masuk ke tab Custom domains di detail konfigurasi service App Runner. Kemudian di halaman tersebut akan tampil informasi DNS record yang perlu ditambahkan. Secara garis besar, nama record tersebut adalah record CNAME untuk validasi certificate di Amazaon Certificate Manager (ACM) dan CNAME untuk nama lain dari default domain service App Runner. Pada contoh di artikel ini, saya tambahkan record tersebut di DNS server saya yang ada di Amazon Route 53 namun detail konfigurasi tidak saya jabarkan lebih detail di blogpost ini.

link-domain

  1. Setelah konfigurasi nama record, tunggu hingga DNS validation atau validasi nama domain selesai. Pastikan validasi sukses.

custom-domain-active

  1. Selanjutnya tes memanggil service dengan nama domain yang sudah dikonfigurasi. Contoh pada aplikasi yang saya buat ini hanyalah API sederhana yang menampilkan kalkulasi Body Mass Index atau index massa badan. Saya coba panggil url nya di browser.

test-api-call

Kesimpulan

Akhirnya kita sampai di penghujung artikel ini. Ada beberapa kesimpulan atau key takeaways yang ingin saya sampaikan:

  • AWS App Runner dapat dijadikan sebagai alternatif jika kita ingin mendeploy web/api service berbasis container dengan mudah tanpa harus memanage infrastruktur lebih lanjut/serverless.
  • Konfigurasi service App Runner dapat dilakukan dengan pendekatan IaC. Sehingga kita memiliki state file dari infrastruktur yang sudah kita buat.

Silahkan kunjungi GitHub repo saya untuk melihat source code konfigurasi yang digunakan dalam artikel ini. Child module untuk template konfigurasi App Runner dengan source container image ECR dapat dilihat di directory App Runner ecr module. Konfigurasi root module untuk App Runner dapat dilihat di directory App Runner root module.

Sekian artikel kali ini. Jika ada saran, kritik, atau masukan silahkan tinggalkan di kolom komentar.

Iklan

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )

Connecting to %s

Situs yang Didukung WordPress.com.

Atas ↑

%d blogger menyukai ini: