Skip to content

Commit a75a4e3

Browse files
committed
docs: add blue=green
1 parent 5bf04a7 commit a75a4e3

File tree

8 files changed

+324
-1
lines changed

8 files changed

+324
-1
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Repository for terraform use cases
1212
|---|---|---|
1313
|Basic EC2|Basic EC2 Setting for testing terraform. | [Link](https://github.com/Terraform-Canvas/terraform-usecases/tree/main/basic-ec2)
1414
|Auto Scailing using AWS | Build auto scailing group for scale in-out.|[Link](https://github.com/Terraform-Canvas/terraform-usecases/tree/main/autoscailing)
15-
|Blue-Green deployment|Build Blue-Green deployment using ALB|TBA
15+
|Blue-Green deployment|Build Blue-Green deployment using ALB|[Link](https://github.com/Terraform-Canvas/terraform-usecases/tree/main/blue-green)
16+
|Blue-Green deployme
1617
|EKS Cluster|Build container cluster system using EKS|TBA|
1718
|Datadog Monitoring|Build monitoring system using Datadog|TBA
1819
|Slack alert|Build slack alert system using AWS Chatbot|TBA

blue-green/blue.tf

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: MPL-2.0
3+
4+
resource "aws_instance" "blue" {
5+
count = var.enable_blue_env ? var.blue_instance_count : 0
6+
7+
ami = data.aws_ami.amazon_linux.id
8+
instance_type = "t2.micro"
9+
subnet_id = module.vpc.private_subnets[count.index % length(module.vpc.private_subnets)]
10+
vpc_security_group_ids = [module.app_security_group.security_group_id]
11+
user_data = templatefile("${path.module}/init-script.sh", {
12+
file_content = "version 1.0 - #${count.index}"
13+
})
14+
15+
tags = {
16+
Name = "blue-${count.index}"
17+
}
18+
}
19+
20+
resource "aws_lb_target_group" "blue" {
21+
name = "blue-tg-${random_pet.app.id}-lb"
22+
port = 80
23+
protocol = "HTTP"
24+
vpc_id = module.vpc.vpc_id
25+
26+
health_check {
27+
port = 80
28+
protocol = "HTTP"
29+
timeout = 5
30+
interval = 10
31+
}
32+
}
33+
34+
resource "aws_lb_target_group_attachment" "blue" {
35+
count = length(aws_instance.blue)
36+
target_group_arn = aws_lb_target_group.blue.arn
37+
target_id = aws_instance.blue[count.index].id
38+
port = 80
39+
}

blue-green/green.tf

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
resource "aws_instance" "green" {
2+
count = var.enable_green_env ? var.green_instance_count : 0
3+
4+
ami = data.aws_ami.amazon_linux.id
5+
instance_type = "t2.micro"
6+
subnet_id = module.vpc.private_subnets[count.index % length(module.vpc.private_subnets)]
7+
vpc_security_group_ids = [module.app_security_group.security_group_id]
8+
user_data = templatefile("${path.module}/init-script.sh", {
9+
file_content = "version 1.1 - #${count.index}"
10+
})
11+
12+
tags = {
13+
Name = "green-${count.index}"
14+
}
15+
}
16+
17+
resource "aws_lb_target_group" "green" {
18+
name = "green-tg-${random_pet.app.id}-lb"
19+
port = 80
20+
protocol = "HTTP"
21+
vpc_id = module.vpc.vpc_id
22+
23+
health_check {
24+
port = 80
25+
protocol = "HTTP"
26+
timeout = 5
27+
interval = 10
28+
}
29+
}
30+
31+
resource "aws_lb_target_group_attachment" "green" {
32+
count = length(aws_instance.green)
33+
target_group_arn = aws_lb_target_group.green.arn
34+
target_id = aws_instance.green[count.index].id
35+
port = 80
36+
}

blue-green/init-script.sh

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/bash
2+
# Copyright (c) HashiCorp, Inc.
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
sudo yum update -y
6+
sudo yum install httpd -y
7+
sudo systemctl enable httpd
8+
sudo systemctl start httpd
9+
echo "${file_content}!" > /var/www/html/index.html

blue-green/main.tf

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: MPL-2.0
3+
4+
provider "aws" {
5+
region = var.region
6+
}
7+
8+
data "aws_availability_zones" "available" {
9+
state = "available"
10+
filter {
11+
name = "opt-in-status"
12+
values = ["opt-in-not-required"]
13+
}
14+
}
15+
16+
module "vpc" {
17+
source = "terraform-aws-modules/vpc/aws"
18+
version = "3.19.0"
19+
20+
name = "main-vpc"
21+
cidr = var.vpc_cidr_block
22+
23+
azs = data.aws_availability_zones.available.names
24+
private_subnets = slice(var.private_subnet_cidr_blocks, 0, var.private_subnet_count)
25+
public_subnets = slice(var.public_subnet_cidr_blocks, 0, var.public_subnet_count)
26+
27+
enable_nat_gateway = true
28+
enable_vpn_gateway = var.enable_vpn_gateway
29+
}
30+
31+
module "app_security_group" {
32+
source = "terraform-aws-modules/security-group/aws//modules/web"
33+
version = "4.17.1"
34+
35+
name = "web-sg"
36+
description = "Security group for web-servers with HTTP ports open within VPC"
37+
vpc_id = module.vpc.vpc_id
38+
39+
ingress_cidr_blocks = [module.vpc.vpc_cidr_block]
40+
}
41+
42+
module "lb_security_group" {
43+
source = "terraform-aws-modules/security-group/aws//modules/web"
44+
version = "4.17.1"
45+
46+
name = "lb-sg"
47+
description = "Security group for load balancer with HTTP ports open to world"
48+
vpc_id = module.vpc.vpc_id
49+
50+
ingress_cidr_blocks = ["0.0.0.0/0"]
51+
}
52+
53+
data "aws_ami" "amazon_linux" {
54+
most_recent = true
55+
owners = ["amazon"]
56+
57+
filter {
58+
name = "name"
59+
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
60+
}
61+
}
62+
63+
resource "random_pet" "app" {
64+
length = 2
65+
separator = "-"
66+
}
67+
68+
resource "aws_lb" "app" {
69+
name = "main-app-${random_pet.app.id}-lb"
70+
internal = false
71+
load_balancer_type = "application"
72+
subnets = module.vpc.public_subnets
73+
security_groups = [module.lb_security_group.security_group_id]
74+
}
75+
76+
resource "aws_lb_listener" "app" {
77+
load_balancer_arn = aws_lb.app.arn
78+
port = "80"
79+
protocol = "HTTP"
80+
81+
default_action {
82+
type = "forward"
83+
forward {
84+
target_group {
85+
arn = aws_lb_target_group.blue.arn
86+
weight = lookup(local.traffic_dist_map[var.traffic_distribution], "blue", 100)
87+
}
88+
target_group {
89+
arn = aws_lb_target_group.green.arn
90+
weight = lookup(local.traffic_dist_map[var.traffic_distribution], "green", 0)
91+
}
92+
stickiness {
93+
enabled = false
94+
duration = 1
95+
}
96+
}
97+
}
98+
}

blue-green/outputs.tf

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: MPL-2.0
3+
4+
output "lb_dns_name" {
5+
value = aws_lb.app.dns_name
6+
}

blue-green/terraform.tf

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: MPL-2.0
3+
4+
terraform {
5+
required_providers {
6+
aws = {
7+
source = "hashicorp/aws"
8+
version = "~> 4.15.0"
9+
}
10+
11+
random = {
12+
source = "hashicorp/random"
13+
version = "3.4.3"
14+
}
15+
}
16+
17+
required_version = "~> 1.4.6"
18+
}

blue-green/variables.tf

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Copyright (c) HashiCorp, Inc.
2+
# SPDX-License-Identifier: MPL-2.0
3+
4+
variable "region" {
5+
description = "The region Terraform deploys your instances"
6+
type = string
7+
default = "us-west-2"
8+
}
9+
10+
variable "vpc_cidr_block" {
11+
description = "CIDR block for VPC"
12+
type = string
13+
default = "10.0.0.0/16"
14+
}
15+
16+
variable "enable_vpn_gateway" {
17+
description = "Enable a VPN gateway in your VPC."
18+
type = bool
19+
default = false
20+
}
21+
22+
variable "public_subnet_count" {
23+
description = "Number of public subnets."
24+
type = number
25+
default = 2
26+
}
27+
28+
variable "private_subnet_count" {
29+
description = "Number of private subnets."
30+
type = number
31+
default = 2
32+
}
33+
34+
variable "public_subnet_cidr_blocks" {
35+
description = "Available cidr blocks for public subnets"
36+
type = list(string)
37+
default = [
38+
"10.0.1.0/24",
39+
"10.0.2.0/24",
40+
"10.0.3.0/24",
41+
"10.0.4.0/24",
42+
"10.0.5.0/24",
43+
"10.0.6.0/24",
44+
"10.0.7.0/24",
45+
"10.0.8.0/24",
46+
]
47+
}
48+
49+
variable "private_subnet_cidr_blocks" {
50+
description = "Available cidr blocks for private subnets"
51+
type = list(string)
52+
default = [
53+
"10.0.101.0/24",
54+
"10.0.102.0/24",
55+
"10.0.103.0/24",
56+
"10.0.104.0/24",
57+
"10.0.105.0/24",
58+
"10.0.106.0/24",
59+
"10.0.107.0/24",
60+
"10.0.108.0/24",
61+
]
62+
}
63+
64+
variable "enable_blue_env" {
65+
description = "Enable blue environment"
66+
type = bool
67+
default = true
68+
}
69+
70+
variable "blue_instance_count" {
71+
description = "Number of instances in blue environment"
72+
type = number
73+
default = 2
74+
}
75+
76+
variable "enable_green_env" {
77+
description = "Enable green environment"
78+
type = bool
79+
default = true
80+
}
81+
82+
variable "green_instance_count" {
83+
description = "Number of instances in green environment"
84+
type = number
85+
default = 2
86+
}
87+
88+
locals {
89+
traffic_dist_map = {
90+
blue = {
91+
blue = 100
92+
green = 0
93+
}
94+
blue-90 = {
95+
blue = 90
96+
green = 10
97+
}
98+
split = {
99+
blue = 50
100+
green = 50
101+
}
102+
green-90 = {
103+
blue = 10
104+
green = 90
105+
}
106+
green = {
107+
blue = 0
108+
green = 100
109+
}
110+
}
111+
}
112+
113+
variable "traffic_distribution" {
114+
description = "Levels of traffic distribution"
115+
type = string
116+
}

0 commit comments

Comments
 (0)