Infrastructure as Code

Infrastructure as Code (IaC) เป็นวิธีการจัดการ infrastructure โดยการเขียนโค้ดแทนที่จะเข้าไปจัดการเป็นเครื่องๆไป ซึ่งทำให้ง่ายต่อการจัดการเซิร์ฟเวอร์จำนวนมากๆ และทำซ้ำได้เรื่อยๆ

Infrastructure ในที่นี้หมายถึงอะไร

ถ้าเป็นยุคก่อน cloud computing เราคงไม่สามารถเขียนโค้ดให้ประกอบเซิร์ฟเวอร์ได้ อย่างมากก็พิมพ์ purchase request/purchase order ให้ฝ่ายจัดซื้อเท่านั้น แต่พอเป็น cloud computing เราสามารถใช้โค้ดสั่งระบบ cloud เช่น AWS ให้สร้าง infrastructure ให้เราได้ ไม่ว่าจะเป็น การจัดการ VPC การกำหนด security rule การวางเซิร์ฟเวอร์ในเครือข่าย

นอกจากนั้น infrastructure อาจรวมถึงซอฟต์แวร์ที่ติดตั้งอยู่บนเซิร์ฟเวอร์อีกด้วย

Code ดีอย่างไร

จริงๆมีหลายวิธีที่สามารถใช้จัดการ infrastructure เช่นการทำเอกสารคู่มือวิธีการติดตั้งเซิร์ฟเวอร์ที่อธิบายรายละเอียด การสร้าง image ต้นฉบับที่เอาไว้คัดลอก แล้วโค้ดดีกว่าอย่างไร

  • โค้ดสามารถเก็บใน SVN/Git ได้ง่าย ซึ่งได้ประโยชน์จาก commit message ว่าใครแก้ไข infrastructure ส่วนไหน เมื่อไร และทำไม
  • โค้ดสามารถอ่านได้ด้วยโปรแกรม text editor ง่ายๆ
  • โค้ดทำซ้ำได้ รันบ่อยๆได้ โดยไม่มีความผิดพลาด

Tool #1 Terraform

เครื่องมือแรกสำหรับการจัดการ IaC คือ Terraform สร้างโดยบริษัท HashiCorp ผู้พัฒนา Consul Vault หรือแม้กระทั่ง Vagrant โดย Terraform ใช้ภาษาของตัวเองที่เรียกว่า HashiCorp Configuration Language (HCL) เพื่อกำหนดค่าต่างๆที่เกี่ยวข้องกับ infrastructure ที่ต้องการ ตัวอย่างเช่น

# main.tf
resource "aws_instance" "web" {
count = 2
instance_type = "m1.small"
ami = "ami-b953f2da"
key_name = "mykeypair"
vpc_security_group_ids = ["sg-9876543"]
subnet_id = "subnet-671927"
}

เมื่อรันคำสั่ง terraform apply โปรแกรมจะสร้าง EC2 instance ทั้งหมด 2 เครื่องด้วยพารามิเตอร์ที่กำหนดเอาไว้ แต่ข้อจำกัดของโค้ดนี้คือมีการ hard code อยู่

# main.tf
resource "aws_instance" "web" {
count = 2
instance_type = "m1.small"
ami = "ami-b953f2da"
key_name = "mykeypair"
vpc_security_group_ids = ["${aws_security_group.default.id}"]
subnet_id = "subnet-671927"
}
resource "aws_security_group" "default" {
name = "terraform_example"
description = "Used in the terraform"
vpc_id = "${aws_vpc.default.id}"
  ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
  ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
  egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

ตัวอย่างนี้ลดการ hard code ของ security group โดยการสร้าง security group ขึ้นมาด้วย terraform แล้วนำผลลัพธ์ที่ได้ (security group id) ไปใช้กับ EC2 Instance ต่อ

Terraform รองคับ cloud provider จำนวนมาก ทั้ง DigitalOcean Azure Google OpenStack และอีกหลายเจ้า และยังใช้เพื่อ provision ในระดับซอฟต์แวร์ได้ด้วย เช่น MySQL PostgreSQL RabbitMQ