<aside> πββοΈ Kakaoenterprise μΈν΄ μν μ€ μ§ννλ λ°ν μλ£μ λλ€.
</aside>
**tf-aws-provider**
γ΄ π global
γ΄ π s3 # Remote State Storage(s3 bucket)
γ΄ π main.tf
γ΄ π output.tf
γ΄ π stage
γ΄ π datastores
γ΄ π mysql # Database
γ΄ π main.tf
γ΄ π var.tf
γ΄ π output.tf
γ΄ π services
γ΄ π webserver-cluster # ASG(EC2 instances) + ELB
γ΄ π main.tf
γ΄ π var.tf
γ΄ π data.tf
γ΄ π output.tf
provider "aws" {
region = "us-east-1"
}
aws_security_group
: resourceaws_launch_configuration
: resourceaws_autoscaling_group
: resourceaws_availability_zones
: datastage/services/webserver-cluster/main.tf
## (1) 보μ κ·Έλ£Ή μ€μ ##
resource "aws_security_group" "elb" {
name = "terraform-elb-instance"
# ν¬νΈ 80λ² νΈλν½μ νμΈν ν, μ°λ
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # μΈν°λ·μ΄ μ°κ²°λ μ΄λκ³³μμλΌλ μ μ
}
# μ€μ 리μμ€μ κ΄λ ¨λ 리μμ€μ΄κΈ°μ create_before_destroy = true
lifecycle {
create_before_destroy = true
}
}
## (2) EC2 μΈμ€ν΄μ€λ₯Ό ASGμ μ€μ νλ μμ κ΅¬μ± ##
resource "aws_launch_configuration" "example"{
image_id = "ami-40d28157"
instance_type = "t2.micro"
security_groups = ["${aws_security_group.elb.id}"]
# EC2 μΈμ€ν΄μ€μ ν¬νΈ λ²νΈλ₯Ό μ€μ νλ λΉμ§λ°μ€ λΆλΆ
# - EC2 μΈμ€ν΄μ€μ μ¬μ©μ λ°μ΄ν° μ€μ μ ν΅ν΄ "Hello, World" μ€ν¬λ¦½νΈλ₯Ό μΈμ€ν΄μ€ κΈ°λμ μνν μ μκ² λλ€.
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" >> index.html
nohup busybox httpd -f -p "${var.server_port}" &
EOF
lifecycle {
create_before_destroy = true
}
}
## (3) ASG μμ± ##
resource "aws_autoscaling_group" "example" {
launch_configuration = "${aws_launch_configuration.example.id}"
availability_zones = "${data.aws_availability_zones.all.names}"
max_size = 10
min_size = 2
tag {
key = "Name"
value = "terraform-asg-example"
propagate_at_launch = true
}
}
stage/services/webserver-cluster/data.tf
## aws κ°μ©μμ κ°μ Έμ€κΈ° ##
data "aws_availability_zones" "all" {
}
stage/services/webserver-cluster/variable.tf
variable "server_port" {
description = "The port the server will use for HTTP requests"
default = 80
}
aws console
μ΄μ ASG λ°°ν¬μ νκ°μ§ λ¬Έμ μ : μ¬λ¬κ°μ μλ²λ₯Ό μ΄μνκΈ° μν΄μλ κ° μλ²μ κ³΅μΈ IPκ° μλ νλμ λν IPκ° μ‘΄μ¬ν΄μΌ ν¨ β λ‘λλ°Έλ°μλ‘ ν΄κ²°
μλΉμ€ νΈλν½μ μμ©νκΈ° μν΄ λ‘λ λ°Έλ°μμ IP νΉμ λλ©μΈ μ΄λ¦μ μλΉμ€ μμ λ ΈμΆν΄μΌν¨. β λμ κ°μ©μ±κ³Ό λ€μν νμ₯μ± λ³΄μ₯
aws_elb
resourcestage/services/webserver-cluster/main.tf
## ELB μμ± ##
resource "aws_elb" "example" {
name = "terraform-asg-example"
availability_zones = "${data.aws_availability_zones.all.names}"
# κΈ°λ³Έμ μΌλ‘ λ€μ΄μ€κ³ λκ°λ νΈλν½μ λν΄ νμ©νμ§ μκ² νκΈ° μν΄, 보μ κ·Έλ£Ήμ ν¬νΈ 80λ² νΈλν½μ λν΄ μ μν΄μΌ ν¨.
security_groups = ["${aws_security_group.elb.id}"]
# νΉμ ν¬νΈμ λν νΈλν½μ λΌμ°ν
νκΈ° μν΄ νλ μ΄μμ 리μ€λλ₯Ό μ€μ
listener {
instance_port = 80
instance_protocol = "http"
lb_port = "${var.server_port}"
lb_protocol = "http"
}
# μνλ₯Ό μ§μμ μΌλ‘ 체ν¬νλ elbμ health check λΈλ‘
# 30 μ΄ λ§λ€ '/' URLλ‘ HTTP μμ²μ νμ¬ ASGμ μλ μΈμ€ν΄μ€ μλ΅μ΄ '200 OK'μΈμ§ νμΈνλ μ€μ
health_check {
healthy_threshold = 2
interval = 30
target = "HTTP:${var.server_port}/"
timeout = 3
unhealthy_threshold = 2
}
}
## ASGμ LB μΆκ° ##
resource "aws_autoscaling_group" "example" {
load_balancers = ["${aws_elb.example.name}"] # μΈμ€ν΄μ€κ° μμν λ ELBμ κ° μΈμ€ν΄μ€λ₯Ό λ±λ‘νλλ‘ ASGμ μμ²
health_check_type = "ELB"
# ..
}
AWS Console
ELB μμ±
aws_s3_bucket
aws_s3_bucket_versioning
/global/s3/main.tf
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "lena-tf-state-bucket"
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_versioning" "versioning-ex" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
aws_dynamodb_table
/global/s3/main.tf
# μν νμΌ μ κΈμ μν DynamoDB μΆκ°
resource "aws_dynamodb_table" "terraform_lock" {
name = "lena-tf-state-bucket-lock"
hash_key = "LockID"
read_capacity = 2
write_capacity = 2
attribute {
name = "LockID"
type = "S"
S3 Backend μ€μ μ s3 bucketκ³Ό dynamodb μΆκ°
terraform {
backend "s3" {
bucket = "lena-tf-state-bucket"
key = "stage/services/webserver-cluster/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "lena-tf-state-bucket-lock"
}
}
Releasing state lock
AWS Console
s3 bucket
dynamoDB
μΉ μλ² ν΄λ¬μ€ν°μμ μΉ μλ²μ λ°°ν¬ μ λ°μ΄νΈλ₯Ό μ§ννλ μμ μ λ°μ΄ν°λ² μ΄μ€μ λ¬Έμ κ° λ°μνμ§ μκΈ°λ₯Ό μνλ€λ©΄ λ°μ΄ν°λ² μ΄μ€ 리μμ€λ₯Ό μμ±νκ³ , λ°μ΄ν°λ² μ΄μ€ μννμΌμ λ§λ€μ΄ μ΄λν μ격 μ€ν 리μ§μμ κ΄λ¦¬ν νμκ° μμ.
aws_db_instance
: resource/stage/datastores/mysql/main.tf
## DBκ° S3μ λͺ¨λ μνλ₯Ό μ μ₯νλλ‘ μ격 μν μ μ₯μλ₯Ό ꡬμ±
terraform {
backend "s3" {
bucket = "lena-tf-state-bucket"
key = "stage/datastores/mysql/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "lena-tf-state-bucket-lock"
}
}
provider "aws" {
region = "us-east-1"
}
## λ°μ΄ν° λ² μ΄μ€ 리μμ€ μμ± ##
resource "aws_db_instance" "example" {
engine = "mysql"
allocated_storage = 10
instance_class = "db.t2.micro"
db_name = "example_data"
username = "admin"
password = "${var.db_password}"
}
TF_VAR_foo
<aside> π« ν λΌνΌμμ λ°μ΄ν°λ² μ΄μ€ ν¨μ€μλμ κ°μ μνΈνλ μ€μνλ€! β λ―Όκ°ν μ 보λ νμΌμ΄λ μ½λμ μ μ₯νμ§ λ§κΈ°
</aside>
/stage/datastores/mysql/var.tf
variable "db_password" {
description = "The password for the database"
}
export TF_VAR_db_password="(λ°μ΄ν°λ² μ΄μ€ ν¨μ€μλ)"
νμν λ°μ΄ν°λ₯Ό μΆλ ₯ λ³μλ‘ λΉΌμ state νμΌμ μ μ₯λλλ‘
output "address" {
value = "${aws_db_instance.example.address}"
}
output "port" {
value = "${aws_db_instance.example.port}"
}