Quick Start: Build & Deploy Aplikasi dengan AWS Fargate

Serverless atau containers? Bagaimana kalau keduanya digabung? Artikel ini menjelaskan secara bertahap bagaimana menjalankan container-based apps secara serverless, dengan AWS Fargate.

Read Now

Donnie Prakoso
Developer, self-proclaimed barista and cafe racer enthusiast. This blog is a collection of my writings on technology.
Published
Monday, September 17, 2018
Info
views
Category
article
Translations
English  

Ada dua layanan dari AWS yang selalu menjadi komponen inti untuk (hampir) semua hasil kerja saya, yaitu AWS Lambda dan Amazon API Gateway. Gagasan untuk tidak perlu repot dalam mengatur infrastruktur dan hanya perlu upload code saya ke cloud, sangatlah berharga untuk saya. Saya hanya perlu menuangkan business logic ke dalam kode dan AWS Lambda akan menjalankannya dan mengatur scaling. Kemudian, saya bisa menghubungkan Lambda saya dengan Amazon API Gateway untuk mengatur rute request ke fungsi Lambda. It’s simply a joy!

Namun, tidak selalu menjalankan system dalam mode serverless menjadi jawaban. Kadang kita juga membutuhkan untuk menjalankan aplikasi berbasis container untuk menjalankan system. Dalam kasus yang umum, kita bisa dengan mudah melakukan konfigurasi Amazon ECS untuk menjalankan aplikasi berbasis Docker. Amazon ECS adalah sebuah layanan dengan performa tinggi dari AWS untuk melakukan orkestrasi aplikasi berbasis Docker. Secara sederhana, Anda bisa menjalankan aplikasi berbasis Docker dengan Amazon ECS dan membiarkan Amazon ECS manage dan scale system Anda. Dengan Amazon ECS, Anda dapat memiliki kumpulan Amazon EC2 instances dimana Amazon ECS akan manage instalasi dan menempatkan container-container Anda ke instance EC2.

A Serverless Container Service

Walaupun demikian, gagasan untuk memiliki sebuah system dengan infrastruktur serverless tetap menarik minat saya karena saya bukan seorang individu yang senang melakukan operations dalam menjalankan infrastruktur. Saya lebih memilih untuk fokus di membangun fitur-fitur sebuah produk. Saya ingin menulis kode saya, menempatkannya ke dalam Docker, dan deploy aplikasi tersebut. Saya ingin melakukan hal yang sama ketika saya develop sebuah aplikasi dengan AWS Lambda. Pendekatan ini sangat berguna ketika Anda tidak memiliki tim development yang besar, seperti yang saya alami di perusahaan startup saya sebelumnya. Dengan meminimalisir kebutuhan untuk melakukan operations di infrastruktur saya, saya memiliki ruang yang lebih dari cukup untuk fokus ke produk saya.

Kalau kasus ini menarik minat Anda, kemungkinan besar Anda akan tertarik dengan AWS Fargate. Dengan AWS Fargate, Anda dapat menjalankan aplikasi berbasis container Anda tanpa perlu repot mengatur server. Terdengar seperti sebuah pendekatan serverless dalam menjalankan aplikasi berbasis container? Ya! Dengan AWS Fargate, saya tidak perlu lagi mengatur infrastruktur saya dan saya bisa mengalokasikan fokus di proses development.

Dalam tulisan kali ini, saya akan sharing bagaimana saya biasanya membangun aplikasi saya untuk keperluan demo di berbagai event menggunakan Fargate. Objektif saya adalah agar Anda memiliki gambaran besar bagaimana Anda dapat membangun dan deploy aplikasi Anda menggunakan Fargate.

Let's Rock!
Tulisan ini adalah sebuah pengenalan terhadap AWS Fargate. Tulisan ini juga dapat menjadi panduan Anda untuk melakukan deploy aplikasi Anda dengan AWS Fargate menggunakan sebuah aplikasi sederhana saya dan sering menjadi basis aplikasi lainnya.

1. Requirements

Ada berbagai cara untuk Anda mengikuti tutorial ini. Sebagai contoh, saya akan menggunakan AWS CLI untuk membuat semua infrastruktur AWS yang diperlukan karena lebih “langsung”, tetapi Anda juga dapat menggunakan dashboard AWS dalam bentuk GUI. Di bawah ini adalah tools yang saya gunakan untuk tulisan kali ini, dan Anda dianjurkan untuk install package-package di bawah ini sebelum Anda memulai tutorialnya.

What do I need? Why? Where I can download it?
Hello Racer code Code repository that used for this tutorial. You can fork or clone this repo. Github
AWS CLI To interact with AWS resources AWS CLI
JQ To make processing JSON file a lot easier 1 JQ
Git If you want to clone my code, you’ll need it for sure Git
Python3 Just in case you are feeling adventurous Python
Docker To package your application Docker
Vim My favorite, beside Sublime Cheatsheet!

1.1 Upgrading AWS CLI

Jangan lupa untuk mendapatkan versi terbaru dari AWS CLI Anda. Untuk melakukan upgrade AWS CLI, Anda dapat menggunakan command berikut di terminal Anda:

pip install awscli --upgrade --user

Setelah Anda menjalankan command ini, Anda akan mendapatkan AWS CLI terbaru dengan fitur-fitur yang dapat digunakan untuk berinteraksi dengan resources Anda di AWS.

2. Write Your Code

Agar lebih mudah, di tulisan kali ini saya akan menggunakan aplikasi sederhana yang saya buat sendiri sebagai demo, dan Anda bisa mendapatkan semua source code yang saya gunakan ketika Anda telah cloning repository saya di Github.

2.1 Code

from flask import Flask, render_template
from flask import jsonify


app = Flask(__name__,static_url_path='/assets',static_folder='assets',template_folder='assets/templates')

@app.route("/ping/")
def ping():
	data = {}
	data["text"]="pong"
	return jsonify(data),200

@app.route("/")
def hello():
	service = {}
	service["text"]="Hello, Racer!"	
	return render_template("index.html", service=service)

if __name__ == "__main__":
	app.run(debug=True, host='0.0.0.0', port=80)

Seperti yang Anda lihat sendiri, ini adalah sebuah aplikasi sederhana berbasis Python3 menggunakan Flask Microframework. Tentunya Anda dapat menggunakan aplikasi yang ANda buat sendiri dan tetap menggunakan step-step yang telah tertera di sini untuk melakukan deployment menggunakan AWS Fargate.

3. Dockerize It!

Setelah kita yakin bahwa aplikasi kita akan berjalan sesuai dengan harapan, sekarang saatnya kita melakukan packaging aplikasi ke dalam bentuk Docker image.

3.1 Create Dockerfile

Dockerfile di bawah ini menggunakan base image python:3.6-slim dan melakukan setting working directory ke path /app setelah melakukan copy semua files yang dibutuhkan ke directory tersebut. Agar aplikasi ini dapat berjalan dengan baik, dilakukan juga pip install agar semua dependencies terinstall. Aplikasi ini lalu akan berjalan di port 80.

FROM python:3.6-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 80
CMD ["python", "app.py"]

3.1 Build, Tag and Push Docker Image

Di bagian ini, yang akan kita lakukan adalah membangun Docker image berdasarkan Dockerfile yang telah kita susun sebelumnya. Setelah kita selesai menciptakan Docker image, kita perlu melakukan push image tersebut ke container repository. Container repository ini berguna sebagai registry yang menyimpan Docker image. Di tulisan ini, saya akan menggunakan Docker Hub untuk sebagai tempat penyimpanan Docker image.

Di bawah ini adalah command-command yang dapat Anda gunakan juga untuk build, tag dan push Docker image Anda ke Docker hub.

docker build -t hello-racer .
docker tag hello-racer:latest <YOUR_DOCKER_ID>/hello-racer:latest
docker push <YOUR_DOCKER_ID>/hello-racer:latest

Anda dapat juga melakukan pull Docker image saya karena saya telah mengaturnya sebagai public image yang di host di Docker Hub, dengan command sebagai berikut:

docker pull donnieprakoso/hello-racer:latest
Amazon ECR
Kalau Anda mencari sebuah container registry yang fully managed, silahkan cek Amazon ECR. Amazon ECR akan menjadi opsi utama Anda jika Anda menginginkan integrasi yang lebih baik dengan Amazon ECS dan layanan-layanan AWS lainnya.

4. Deploy Application with AWS Fargate

4.1 Create IAM Roles

Bagian ini akan memandu Anda bagaimana Anda dapat menciptakan IAM role yang akan Anda butuhkan di dalam task definition 2. IAM role ini akan membantu Amazon ECS untuk mendapatkan permission ketika menjalankan aplikasi. Tidak ada yang sulit di sini karena di dalam tutorial ini kita hanya perlu mencantumkan 2 policy yang sudah ada, yaitu AmazonECSTaskExecutionRolePolicy and CloudWatchLogsFullAccess. Jika Anda melakukan clone repository saya, Anda akan mendapatkan semua file yang dibutuhkan di dalam direktori /aws.

export HELLO_RACER_IAM_TASK_ROLE=`aws iam create-role --role-name "helloRacer-executionRole" --assume-role-policy-document file://aws/iam-trustPolicy-task.json | jq -c '.Role.Arn'`
Ini Penting!
Satu hal yang sering terjadi ketika Anda menggunakan CLI adalah keseringan untuk lupa beberapa value yang diperlukan di dalam step berikutnya. Jadi, Anda perlu mencatat value tersebut. Di sisi lain, command di atas akan membantu Anda untuk menyimpan value yang diperlukan dengan bantuan tool JQ dan melakukan export ke environment variable, di mana Anda dapat mengambilnya lagi.

Di langkah ini, kini Anda memiliki semua IAM role yang diperlukan. Sekarang, kita akan melakukan attach policy tersebut ke IAM role sehingga Amazon ECS dapat menjalankan aplikasi kita.

aws iam attach-role-policy --role-name helloRacer-executionRole --policy-arn "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"

aws iam attach-role-policy --role-name helloRacer-executionRole --policy-arn "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"

4.2 Create Task Definition

Sekarang hal yang paling seru. Ingat tentang task definition 2? Sangatlah penting untuk menciptakan task definition sebelum melakukan deployment untuk aplikasi Anda agar Amazon ECS paham konfigurasi yang dibutuhkan.

Di dalam folder /aws, Anda akan mendapatkan task definition yang telah saya susun dalam format JSON. Jika Anda lihat ke dalam file tersebut, Anda akan mendapatkan variable yang harus diganti dengan ARN dari IAM role yang telah Anda ciptakan. Anda dapat melakukan ini dengan dua cara, dengan melakukan edit secara langsung, atau cara yang lebih simple adalah menggunakan tool sed untuk keperluan ini. Di bawah ini adalah penggunaan sed yang dapat Anda gunakan:

sed -e "s|REPLACE_ME_WITH_HELLO_RACER_IAM_TASK_ROLE|$HELLO_RACER_IAM_TASK_ROLE|g" aws/ecs-task-definition.json > output/ecs-task-definition.json

Setelah Anda melakukan command di atas, Anda akan menemukan hasilnya di dalam folder /output yang dapat Anda gunakan untuk mendaftarkan task definition ini di dalam Amazon ECS dengan command berikut:

aws ecs register-task-definition --cli-input-json file://output/ecs-task-definition.json

4.3 Create A Cluster

Kini kita telah mendaftarkan task definition. Selanjutnya, yang perlu kita lakukan adalah menciptakan sebuah cluster. Command di bawah ini akan membantu Anda menciptakan sebuah cluster di mana yang akan digunakan untuk menempatkan aplikasi kita:

export HELLO_RACER_CLUSTER_ARN=`aws ecs create-cluster --cluster-name "hello-racer" | jq -c '.cluster.clusterArn'`

4.4 Prepare Your VPC and Security Group

Karena tidak ada keperluan spesifik di dalam networking, kita dapat menggunakan VPC default yang kita punya. Anda dapat menggunakan command di bawah ini untuk mendapatkan ID dari VPC default Anda:

aws ec2 describe-vpcs

Untungnya, jika Anda telah melakukan instalasi JQ, Anda dapat menggunakan command berikut untuk mendapatkan ID default dari VPC Anda sekaligus menyimpannya dalam environment variable:

export HELLO_RACER_VPC_ID=`aws ec2 describe-vpcs | jq -c '.Vpcs[] | select(.IsDefault == true) | .VpcId'`

Sekarang yang kita butuhkan adalah menciptakan sebuah security group dan mengijinkan port 80 sebagai inbound rule sehingga kita dapat mengaksesnya:

export HELLO_RACER_SECURITY_GROUP_ID=`aws ec2 create-security-group --group-name "securityGroup-helloRacer" --description "Security Group for helloRacer" | jq -c '.GroupId'`
aws ec2 authorize-security-group-ingress --group-name "securityGroup-helloRacer" --protocol tcp --port 80 --cidr 0.0.0.0/0

4.5 Deploy using AWS Fargate

Di titik ini, kita di dalam stage terakhir dan yang perlu kita lakukan adalah melakukan deploy aplikasi kita dengan AWS Fargate. Service, di dalam konteks Amazon ECS, mengijinkan Anda untuk menjalankan dan melakukan setting jumlah container di dalam sebuah task definition secara bersamaan di dalam cluster Amazon ECS. Bagi saya, service merupakan sebuah elemen yang dapat menggabungkan task definition, security groups, subnets, dan juga jumlah container/task yang ingin kita jalankan.

Untuk menciptakan sebuah service, kita perlu mengisi terlebih dahulu file /aws/ecs-create-service.json dengan variabel yang diperlukan. Pertanya, kita membutuhkan ID dari subnet network kita dan menyimpannya dalam environment variabel:

export HELLO_RACER_SUBNET_ID=`aws ec2 describe-subnets | jq -c "[.Subnets[] | select(.VpcId==$HELLO_RACER_VPC_ID)][0] | .SubnetId"`

Sekarang Anda memiliki semua environment vairables yang diperlukan, jika Anda melakukan:

echo $HELLO_RACER_

…dan melakukan double tab, Anda dapat melihat variabel-variabel berikut yang telah Anda ciptakan dalam langkah sebelumnya:

  • HELLO_RACER_CLUSTER_ARN
  • HELLO_RACER_IAM_TASK_ROLE
  • HELLO_RACER_SECURITY_GROUP_ID
  • HELLO_RACER_SUBNET_ID
  • HELLO_RACER_VPC_ID

Sekarang, yang kita perlu lakukan adalah mengubah file /aws/ecs-create-service.json dengan variabel yang telah kita miliki untuk menciptakan sebuah service:

sed -e "s|REPLACE_ME_WITH_HELLO_RACER_SUBNET_ID|$HELLO_RACER_SUBNET_ID|g"  -e "s|REPLACE_ME_WITH_HELLO_RACER_SECURITY_GROUP_ID|$HELLO_RACER_SECURITY_GROUP_ID|g" aws/ecs-create-service.json > output/ecs-create-service.json

Sekarang Anda dapat melakukan service dengan command berikut:

aws ecs create-service --cli-input-json file://output/ecs-create-service.json

Sekarang proses pembuatan service sedang berlangsung. Anda dapat melakukan monitoring proses ini dengan menggunakan command aws ecs wait dengan cara:

aws ecs wait services-stable --services svc-hello-racer --cluster hello-racer

Jika Anda melakukan setiap langkah dengan benar, maka Anda telah melakukan deployment untuk aplikasi Anda menggunakan AWS Fargate. Keren!

4.6 Test Your Application

Sekarang saatnya untuk melakukan testing! Tutorial ini hanya melakukan deployment untuk 1 task saja dan Fargate akan mengalokasikan sebuah public IP address untuk task yang baru saja Anda ciptakan. Sekarang kita perlu untuk mendapatkan public IP address tersebut dan membukanya dengan bentuk URL di dalam browser.

Semua task di Amazon ECS memiliki ARN tersendiri, dan karena kita hanya deployment 1 task saja, kita dapat mengambil value tersebut dari index array pertama. Dari situ, kita akan membutuhkan Elastic Network Interface yang telah terpasang terhadap task untuk mendapatkan public IP. Ikuti rangkaian command di bawah ini untuk mendapatkan public IP task Anda:

export HELLO_RACER_TASK_ARN=`aws ecs list-tasks --cluster hello-racer --output json --query "taskArns[0]"`
export HELLO_RACER_TASK_ID=`echo $HELLO_RACER_TASK_ARN | sed -e 's|"||g' | cut -f 2 -d "/"`
export HELLO_RACER_TASK_ENI_ID=`aws ecs describe-tasks --tasks $HELLO_RACER_TASK_ID --cluster hello-racer | jq -c '.tasks[0].attachments[0].details[] | select(.name=="networkInterfaceId") | .value'`
aws ec2 describe-network-interfaces --network-interface-ids "[$HELLO_RACER_TASK_ENI_ID]" | jq -c '.NetworkInterfaces[].PrivateIpAddresses[].Association.PublicIp'

Di command terakhir, aws ec2 describe-network-interfaces, akan memberikan anda alamat public IP yang telah diasosiasikan dengan task Anda. Kini, yang perlu Anda lakukan adalah membuka IP tersebut dengan browser. Ketika Anda membukanya di browser, Anda akan melihat tampilan sebagai berikut:

Web screenshot

4.7 Cleaning Up

Ketika Anda telah selesai dengan tutorial ini, jangan lupa untuk menghapus semua resource AWS atau Anda akan terkena biaya tambahan. Untuk membantu Anda mengingat semua resource yang digunakan dalam tutorial ini, saya telah menyiapkan sebuah checklist jadi tidak akan terlupa oleh Anda. Anda dapat dengan mudah menggunakan AWS console untuk menghapus semua resource yang diciptakan dalam tutorial ini.

What We’ve Learned

Jika Anda mengikuti tutorial ini dengan benar, Anda kini memiliki sebuah aplikasi berbasis Docker yang dideploy dengan AWS Fargate. Congratulations!

Sebagai ringkasan, di bawah ini adalah langkah yang diperlukan untuk melakukan deployment aplikasi Anda menggunakan AWS Fargate:

Next Steps

Memahami bagaimana deploy aplikasi Anda dengan AWS Fargate memberikan fondasi dasar bagi Anda sebelum membawa aplikasi Anda ke tingkatan berikut. Beberapa ide dari saya bagaimana Anda bisa melanjutkan dari sini adalah melakukan konfigurasi CI/CD dengan AWS Fargate, AWS Code Pipeline dan AWS Code Build, atau melakukan konfigurasi Elastic Load Balancer dan juga auto-scaling dengan AWS Fargate.

Bagi Anda yang ingin mempelajari lebih lanjut, berikut beberapa links yang dapat berguna untuk Anda:

Jika Anda memiliki pertanyaan atau ingin mendiskusikan topik ini lebih lanjut dengan saya, silahkan ping saya di Twitter @donnieprakoso.

GO BUILD!


  1. AWS CLI juga memiliki built-in JQ untuk query yang sederhana. Namun, karena kita akan menggunakan query yang custom, sangat disarankan untuk menginstall JQ. [return]
  2. Task definition adalah rangkaian instruksi yang memberitahukan Amazon ECS bagaimana menjalankan Docker containers. Dengan kata lain, task definition adalah blueprint untuk aplikasi Anda. [return]
Like this article?
Give this article a love or you can share this article with others.
Read Next
[Opening Soon] AWS Region di Indonesia!

Berita baru dari AWS yang akan meluncurkan region baru di Indonesia. Artikel ini mengulas konsep Region dan Availability Zone di AWS yang penting untuk dipahami dari berita tersebut.

Read More
Previously
Ssst, Rahasia!

AWS Secrets Manager adalah sebuah layanan yang dapat kita gunakan untuk menyimpan credential, password, atau informasi sensitif yang digunakan di dalam aplikasi kita. Artikel ini mengulas secara singkat bagaimana cara penggunaannya.

Read More

Published
Monday, September 17, 2018
Info
views
Category
article
Translations

Donnie Prakoso
Developer, self-proclaimed barista and cafe racer enthusiast. This blog is a collection of my writings on technology.

Codes & Notes. by Donnie Prakoso
© @donnieprakoso · 2019