SlideShare a Scribd company logo
1 of 101
Download to read offline
EVOLVING YOUR INFRASTRUCTURE
WITH TERRAFORM
Nicki Watt - CTO

@techiewatt
12-06-2017
ABOUT ME / OPENCREDO
▸OpenCredo CTO
▸Premiere HashiCorp partner
▸Hands on software development
consultancy
▸Cloud, Data Engineering, DevSecOps
2
AGENDA
▸Evolving your Terraform
▸Orchestrating your Terraform
▸Conclusion
3
4
Evolving your Terraform

(a journey from a client’s perspective)
6
Example: E-Commerce System in AWS

(delivered as a Micro-services architecture) 

7
Sample System


Simple 

Kubernetes
(K8S) 

Environment
8
public DMZ & Bastion Box
k8s clusterSample System


Simple 

Kubernetes
(K8S) 

Environment
database (RDS)
9
Pass #1 -
In the beginning …
10
https://github.com/mycompany/myproject
terraform.tf
## Test VPC
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bastion
resource "aws_instance" “test_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . .
}


- terraform-prod.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
11
We must to go to production this
week …
terraform.tf
## Test VPC
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bastion
resource "aws_instance" “test_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . .
}
## Prod VPC
resource "aws_vpc" "prod" {
cidr_block = "172.16.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
12
https://github.com/mycompany/myproject


- terraform-prod.tfbkp

- terraform.tf

- terraform.tfvars

- terraform.tfstate
terraform-test.tf
## Test VPC
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bast-ion
resource "aws_instance" “test_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . .
}
## Prod VPC
resource "aws_vpc" "prod" {
cidr_block = "10.0.0.3/24"
enable_dns_support = true
enable_dns_hostnames = true
}
13
https://github.com/mycompany/myproject
terraform-prod.tf
## Prod VPC
resource "aws_vpc" "prod" {
cidr_block = "172.16.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bastion
resource "aws_instance" “prod_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . .


- terraform-prod.tf

- terraform-test.tf

- terraform.tfvars

- terraform.tfstate
14
Need an upgraded CIDR range
in TEST …
15


- terraform-prod.tfbkp

- terraform-test.tf

- terraform.tfvars

- terraform.tfstate
https://github.com/mycompany/myproject
terraform-test.tf
## Test VPC
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bast-ion
resource "aws_instance" “test_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . .
}
## Prod VPC
resource "aws_vpc" "prod" {
cidr_block = "10.0.0.3/24"
enable_dns_support = true
enable_dns_hostnames = true
}
terraform-prod.tf
## Prod VPC
resource "aws_vpc" "prod" {
cidr_block = "172.16.0.0/21"
enable_dns_support = true
enable_dns_hostnames = true
}
## Staging Bastion
resource "aws_instance" “prod_bastion" {
ami = "ami-7abd5555"
instance_type = "t2.large"
. . . 15
16
Help!
I seem to have deleted production
17
“terralith"
https://sites.google.com/site/laurenmcnanyspln/magnetic-fields
▸Single state file
▸Single definition file
▸Hard coded config
▸Local state
Terralith: Characteristics
18
▸Can’t manage environments separately
▸Config not that intuitive 

(big ball of mud)
▸Maintenance challenge: Duplicate Defs
(not DRY)
Terralith - Pain points
19
20
Pass #2
21
“multi terralith"
https://sites.google.com/site/laurenmcnanyspln/magnetic-fields
▸Envs - Separate State Management
▸Multiple Terraform Definition Files
▸Better Use of Variables
Multi Terralith: Characteristics
22
+ test

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
23
https://github.com/mycompany/myproject
networks.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = true
enable_dns_hostnames = true
}
vms.tf
resource "aws_instance" "node" {
count = "${var.node_count}"
ami = "ami-7abd5555"
instance_type = “${var.vm_type}”
. . .
}
+ prod

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
24
https://github.com/mycompany/myproject
networks.tf
resource "aws_vpc" "core" {
cidr_block = “${var.cidr}”
enable_dns_support = true
enable_dns_hostnames = true
}
vms.tf
resource "aws_instance" "node" {
count = "${var.node_count}"
ami = "ami-7abd5555"
instance_type = “${var.vm_type}”
. . .
}
+ test

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
+ prod

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
+ test

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
25
https://github.com/mycompany/myproject
networks.tf
resource "aws_vpc" "core" {
cidr_block = “${var.cidr}”
enable_dns_support = true
enable_dns_hostnames = true
}
vms.tf
resource "aws_instance" "node" {
count = "${var.node_count}"
ami = "ami-7abd5555"
instance_type = “${var.vm_type}”
. . .
}
+ prod

- networks.tf

- vms.tf

- terraform.tfvars

- terraform.tfstate
Terralith - (recap)
26
▸Can’t manage environments separately

▸Config not that intuitive 

(big ball of mud)
▸Maintenance challenge: Duplicate Defs
(not DRY)
Multi Terralith
27
▸Manage environment separately

(separate state files per env)
▸More intuitive configuration

(multiple files)
▸Maintenance challenge: Duplicate Defs
(not DRY)
✅
"
28
Pass #3
29
“terramod"
Alan Chia (https://commons.wikimedia.org/wiki/File:Lego_Color_Bricks.jpg)
▸Reusable modules
▸Envs compose themselves from modules
▸Restructuring of repo
30
Terramod: Characteristics
31
database
core
k8s-cluster
32
database
core
k8s-cluster
- VPC

- All Subnets

- Core Routing & Gateways

- Bastion Host (OpenVPN server)
- Instances

- Security Groups
- Amazon RDS

- DB Subnet Group
33
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

https://github.com/mycompany/myproject
separate env management &
module defs
34
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

https://github.com/mycompany/myproject
define logical components as
re-usable modules
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

35
https://github.com/mycompany/myproject
core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
resource "aws_subnet" "private" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.priv_cidr}"
...
}
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

36
https://github.com/mycompany/myproject
core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
resource "aws_subnet" "private" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.priv_cidr}"
...
}
input.tf
variable "cidr" {}
variable "dns” {}
variable "dnsh" {}
variable "dmz_cidr" {}
variable "priv_cidr" {}
...
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

37
https://github.com/mycompany/myproject
core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
resource "aws_subnet" "private" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.priv_cidr}"
...
}
input.tf
variable "cidr" {}
variable "dns” {}
variable "dnsh" {}
variable "dmz_cidr" {}
variable "priv_cidr" {}
...
output.tf
output "priv_subnet_id" {
value ="${aws_subnet.private.id}"
}
...
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

38
https://github.com/mycompany/myproject
defines the contract of the
module
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

39
https://github.com/mycompany/myproject
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = 

"${module.core.priv_subnet_id}"
}
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

40
https://github.com/mycompany/myproject
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = 

"${module.core.priv_subnet_id}"
}
+ envs/[test|prod]

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

41
https://github.com/mycompany/myproject
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = 

"${module.core.priv_subnet_id}"
}
▸Manage environment separately

(separate state files per env)
▸More intuitive configuration

(multiple files)
▸Maintenance challenge: Duplicate Defs
(not DRY)
Multi Terralith
42
✅
"
▸Manage environment separately

(separate state files per env)
▸Intuitive configuration

(reusable modules)
▸Reduced Duplicate Definitions 

(DRYer)
Terramod
43
✅
"
✅
44
Pass #4
45
Alan Chia (https://commons.wikimedia.org/wiki/File:Lego_Color_Bricks.jpg)
terramod
Marcos Leal (https://commons.wikimedia.org/wiki/File:Army_(2995294027).jpg)
n
▸Nested modules
▸base modules

(low level infrastructure specific)
▸logical modules

(system specific)
▸Sometimes dedicated module repo
46
Terramod : Characteristics
n
47
https://github.com/mycompany/myproject
+ envs

+ modules

+ project

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- k8s.tf

- output.tf

logical (system specific) modules
48
https://github.com/mycompany/myproject
+ envs

+ modules

+ common

+ aws

+ network

+ vpc

+ pub_subnet

+ priv_subnet

+ comps

+ instance

+ db-instance

+ envs

+ modules

+ project

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- k8s.tf

- output.tf

logical (system specific) modules base (infra specific) modules
49
https://github.com/mycompany/myproject
+ envs

+ modules

+ common

+ aws

+ network

+ vpc

+ pub_subnet

+ priv_subnet

+ comps

+ instance

+ db-instance

+ envs

+ modules

+ project

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- k8s.tf

- output.tf

modules/project/core/core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
modules/project/core/core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
+ envs

+ modules

+ project

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- k8s.tf

- output.tf

50
https://github.com/mycompany/myproject
modules/project/core/core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
+ envs

+ modules

+ common

+ aws

+ network

+ vpc

+ pub_subnet

+ priv_subnet

+ comps

+ instance

+ db-instance

50
https://github.com/mycompany/myproject
modules/project/core/core.tf
module "vpc" {
source = "../../common/aws/net/vpc"
cidr = "${var.vpc_cidr}"
}
module "dmz-subnet" {
source = "../../common/aws/net/pub-subnet"
vpc_id = "${module.vpc.vpc_id}"
subnet_cidrs = [ “${var.dmz_cidr}” ]
}
module "priv-subnet" {
source = "../../common/aws/net/priv-subnet"
vpc_id = "${module.vpc.vpc_id}"
subnet_cidrs = [ “${var.priv_cidr}” ]
+ envs

+ modules

+ common

+ aws

+ network

+ vpc

+ pub_subnet

+ priv_subnet

+ comps

+ instance

+ db-instance

modules/project/core/core.tf
resource "aws_vpc" "core" {
cidr_block = "${var.cidr}"
enable_dns_support = "${var.dns}"
enable_dns_hostnames = "${var.dnsh}"
}
resource "aws_subnet" "dmz" {
vpc_id = "${aws_vpc.core.id}"
cidr_block = "${var.dmz_cidr}"
map_public_ip_on_launch = 1
...
}
51
https://github.com/mycompany/myproject
modules/project/core/core.tf
module "vpc" {
source = "../../common/aws/net/vpc"
cidr = "${var.vpc_cidr}"
}
module "dmz-subnet" {
source = "../../common/aws/net/pub-subnet"
vpc_id = "${module.vpc.vpc_id}"
subnet_cidrs = [ “${var.dmz_cidr}” ]
}
module "priv-subnet" {
source = "../../common/aws/net/priv-subnet"
vpc_id = "${module.vpc.vpc_id}"
subnet_cidrs = [ “${var.priv_cidr}” ]
BUT …
Issue #953 - Support the count parameter for modules
▸Manage environment separately

(separate state files per env)
▸Intuitive configuration

(reusable modules)
▸Reduced Duplicate Definitions 

(DRYer)
Terramod (recap)
52
✅
"
✅
▸Manage environment separately

(separate state files per env)
▸Intuitive configuration

(reusable modules)
▸Reduced Duplicate Definitions further 

(as DRY as possible given restrictions)
Terramod
53
n
✅
"
✅
54
Time goes on …
55
Maintenance required …

- Make bastion box smaller -
+ envs/prod

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

56
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
bastion_flav = "${var.bastion_flav}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
node_flavour = "${var.bastion_flav}"
}
terraform.tfvars
vpc_cidr = “10.0.0.0/21”
bastion_flav = “r4.large”
node_flavour = “m4.4xlarge”
+ envs/prod

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

57
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
bastion_flav = "${var.bastion_flav}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
node_flavour = "${var.bastion_flav}"
}
terraform.tfvars
vpc_cidr = “10.0.0.0/21”
bastion_flav = “m4.large”
node_flavour = “m4.4xlarge”
+ envs/prod

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

58
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
bastion_flav = "${var.bastion_flav}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
node_flavour = "${var.bastion_flav}"
}
terraform.tfvars
vpc_cidr = “10.0.0.0/21”
bastion_flav = “m4.large”
node_flavour = “m4.4xlarge”
59
Help!
I seem to be rebuilding the K8S cluster!
+ envs/prod

- config.tf

- terraform.tf

- terraform.tfvars

- terraform.tfstate
+ modules

+ core

- input.tf

- core.tf

- output.tf

+ k8s-cluster

- input.tf

- dns.tf

- vms.tf

- output.tf

60
terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
bastion_flav = "${var.bastion_flav}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
node_flavour = "${var.bastion_flav}"
}
terraform.tfvars
vpc_cidr = “10.0.0.0/21”
bastion_flav = “m4.large”
node_flavour = “m4.4xlarge”
OOPS! Typo
▸Can’t manage logical parts of our
infrastructure independently
Next set of pain!
61
62
Pass #5
63
“terraservices"
https://commons.wikimedia.org/wiki/File:Caffeine_Molecule.png
▸ Independent management of logical comps
▸ Isolates & Reduces Risk
▸ Aids with Multi Team Setups
▸Distributed (Remote State)
▸Requires additional orchestration effort
Terraservices - Characteristics
64
65
database
core
k8s-cluster
- VPC

- All Subnets

- Core Routing & Gateways

- Bastion Host (OpenVPN server)
- Instances

- Security Groups
- Amazon RDS

- DB Subnet Group
+ envs

+ test



- ...

- ...

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

- ...

- ...

+ k8s-cluster

- ...
66
- terraform.tfstate

- terraform.tfvars

- xxx.tf
Terraservices - Repo Structure
From
67
- terraform.tfstate

- terraform.tfvars

- xxx.tf
To
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
Terraservices - Repo Structure
+ envs

+ test



- ...

- ...

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

- ...

- ...

+ k8s-cluster

- ...
68
envs/test/terraform.tf
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
dmz_cidr = "${var.dmz_cidr}"
priv_cidr = "${var.priv_cidr}"
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = 

"${module.core.priv_subnet_id}"
}
Terramod - Connecting (recap)
From
69
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
envs/test/core/terraform.tf
# Optional but explicit! (Needs 0.9+)
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
envs/test/core/outputs.tf
output "priv_subnet_id" {
value ="${module.core.priv_subnet_id}"
}
Terraservices - Connecting
To
70
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
envs/test/core/terraform.tf
# Optional but explicit! (Needs 0.9+)
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
envs/test/core/outputs.tf
output "priv_subnet_id" {
value ="${aws_subnet.private.id}"
}
envs/test/k8s-cluster/terraform.tf
data "terraform_remote_state" "core" {
backend = "local"
config {
path = “../core/terraform.tfstate"
}
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = “${data.terraform_remote_
state.core.priv_subnet_id}"
}

}
Terraservices - Connecting
To
Terraservices - Characteristics
71
▸ Independent management of logical comps
▸ Isolates & Reduces Risk
▸ Aids with Multi Team Setups
▸Distributed (Remote State)
▸Requires additional orchestration effort
72
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
envs/test/core/terraform.tf
# Optional but explicit! (Needs 0.9+)
terraform {
backend "local" {
path = "terraform.tfstate"
}
}
module "core" {
source = "../../modules/core"
cidr = "${var.vpc_cidr}"
envs/test/core/outputs.tf
output "priv_subnet_id" {
value ="${module.core.priv_subnet_id}"
}
Terraservices - Distributed (Remote State)
From
73
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
envs/test/core/terraform.tf
# Optional but explicit! (Needs 0.9+)
terraform {
backend "s3" {
region = "eu-west-1"
bucket = "myco/myproj/test"
key = "core/terraform.tfstate"
encrypt = "true"
}
}
envs/test/core/outputs.tf
output "priv_subnet_id" {
value ="${module.core.priv_subnet_id}"
}
Terraservices - Distributed (Remote State)
To
74
+ envs

+ test

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...
envs/test/core/terraform.tf
# Optional but explicit! (Needs 0.9+)
terraform {
backend "s3" {
region = "eu-west-1"
bucket = "myco/myproj/test"
key = "core/terraform.tfstate"
encrypt = "true"
}
}
envs/test/core/outputs.tf
output "priv_subnet_id" {
value ="${module.core.priv_subnet_id}"
}
Terraservices - Distributed (Remote State)
To
envs/test/k8s-cluster/terraform.tf
data "terraform_remote_state" "core" {
backend = "s3"
config {
region = "eu-west-1"
bucket = "myco/myproj/test"
key = "core/terraform.tfstate"
encrypt = "true"
}
}
module "k8s-cluster" {
source = "../../modules/k8s-cluster"
num_nodes = "${var.k8s_nodes}"
priv_subnet = “${data.terraform_remote_
state.core.priv_subnet_id}"
75
+ envs

+ test|prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ modules

+ common

+ aws

+ network

+ vpc

Terraservices - Repo Isolation (Optional)
https://github.com/myco/myproj
From
76
+ envs

+ test|prod

+ core

- ...

+ database

- ...

+ k8s-cluster

- ...



+ modules

+ common

+ aws

+ network

+ vpc

Terraservices - Repo Isolation (Optional)
https://github.com/myco/myproj
https://github.com/myco/myproj-core
https://github.com/myco/myproj-db
https://github.com/myco/myproj-k8s
https://github.com/myco/tf-modcomm
To
Terraservices - Characteristics
77
▸ Independent management of logical comps
▸ Isolates & Reduces Risk
▸ Aids with Multi Team Setups
▸Distributed (Remote State)
▸Requires additional orchestration effort
78
Orchestrating your Terraform
79
database
core
k8s-cluster
80
database
core
k8s-cluster
81
Orchestration System
82
Orchestration System
Laptop, Local State 

& READMEs
83
Orchestration System
Laptop, Local State 

& READMEs
84
Orchestration System
Laptops, Local State 

& READMEs
85
Orchestration System
Laptops, Local State 

& READMEs
Remote State
86
Orchestration System
Laptops, Local State 

& READMEs
Remote State
87
Orchestration System
Laptops, Remote State, 

Shared Services,

& READMEs
88
Orchestration System
Who builds the
infrastructure
that builds the
infrastructure ?
89
Orchestration System
Jenkins, Remote State,

Custom Scripts, 

Shared Services,

& READMEs
90
Orchestration System
Custom Systems 

& Tooling
91
Orchestration System
SaaS Offerings
(HashiCorp Enterprise
Products)
92
It’s not just about the structure of the
code …
You also need to evolve your
supporting orchestration system &
processes
93
Conclusion
94
Evolving Terraform Setup
95
EVOLVING YOUR TERRAFORM SETUP
▸Terralith
▸Multi Terralith - Envs: Independent management
▸Terramod
▸Terramod - Modules : Maintainability & Reuse
▸Terraservices - Logical Components: Independent

management
n
96
EVOLVING YOUR TERRAFORM SETUP
▸Terralith
▸Multi Terralith - Envs: Independent management
▸Terramod
▸Terramod - Modules : Maintainability & Reuse
▸Terraservices - Logical Components: Independent

management
n
97
EVOLVING YOUR TERRAFORM SETUP
▸Terralith
▸Multi Terralith - Envs: Independent management
▸Terramod
▸Terramod - Modules : Maintainability & Reuse
▸Terraservices - Logical Components: Independent

management
n
98
EVOLVING YOUR TERRAFORM SETUP
▸Terralith
▸Multi Terralith - Envs: Independent management
▸Terramod
▸Terramod - Modules : Maintainability & Reuse
▸Terraservices - Logical Components: Independent

management
n
99
EVOLVING YOUR TERRAFORM SETUP
▸Terralith
▸Multi Terralith - Envs: Independent management
▸Terramod
▸Terramod - Modules : Maintainability & Reuse
▸Terraservices - Logical Components: Independent

management
n
100
Also need to consider how to
evolve the management &
orchestration of Terraform
101
Thanks!
@techiewatt

More Related Content

What's hot

Webinar slides: An Introduction to Performance Monitoring for PostgreSQL
Webinar slides: An Introduction to Performance Monitoring for PostgreSQLWebinar slides: An Introduction to Performance Monitoring for PostgreSQL
Webinar slides: An Introduction to Performance Monitoring for PostgreSQL
Severalnines
 
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
Amazon Web Services Korea
 
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
Databricks
 

What's hot (20)

YARN Ready: Integrating to YARN with Tez
YARN Ready: Integrating to YARN with Tez YARN Ready: Integrating to YARN with Tez
YARN Ready: Integrating to YARN with Tez
 
Amazon Redshift의 이해와 활용 (김용우) - AWS DB Day
Amazon Redshift의 이해와 활용 (김용우) - AWS DB DayAmazon Redshift의 이해와 활용 (김용우) - AWS DB Day
Amazon Redshift의 이해와 활용 (김용우) - AWS DB Day
 
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin HuaiA Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
A Deep Dive into Spark SQL's Catalyst Optimizer with Yin Huai
 
Webinar slides: An Introduction to Performance Monitoring for PostgreSQL
Webinar slides: An Introduction to Performance Monitoring for PostgreSQLWebinar slides: An Introduction to Performance Monitoring for PostgreSQL
Webinar slides: An Introduction to Performance Monitoring for PostgreSQL
 
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
 
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
 
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
실전! AWS 기반 데이터베이스 마이그레이션::최홍식::AWS Summit Seoul 2018
 
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
Designing ETL Pipelines with Structured Streaming and Delta Lake—How to Archi...
 
How Netflix Tunes EC2 Instances for Performance
How Netflix Tunes EC2 Instances for PerformanceHow Netflix Tunes EC2 Instances for Performance
How Netflix Tunes EC2 Instances for Performance
 
Introduction to Apache Spark Ecosystem
Introduction to Apache Spark EcosystemIntroduction to Apache Spark Ecosystem
Introduction to Apache Spark Ecosystem
 
Introduction to Amazon Web Services - How to Scale your Next Idea on AWS : A ...
Introduction to Amazon Web Services - How to Scale your Next Idea on AWS : A ...Introduction to Amazon Web Services - How to Scale your Next Idea on AWS : A ...
Introduction to Amazon Web Services - How to Scale your Next Idea on AWS : A ...
 
MySQL InnoDB Cluster and Group Replication in a Nutshell: hands-on tutorial
MySQL InnoDB Cluster and Group Replication in a Nutshell:  hands-on tutorialMySQL InnoDB Cluster and Group Replication in a Nutshell:  hands-on tutorial
MySQL InnoDB Cluster and Group Replication in a Nutshell: hands-on tutorial
 
Deep dive into flink interval join
Deep dive into flink interval joinDeep dive into flink interval join
Deep dive into flink interval join
 
MSA 전략 2: 마이크로서비스, 어떻게 구현할 것인가?
MSA 전략 2: 마이크로서비스, 어떻게 구현할 것인가?MSA 전략 2: 마이크로서비스, 어떻게 구현할 것인가?
MSA 전략 2: 마이크로서비스, 어떻게 구현할 것인가?
 
아름답고 유연한 데이터 파이프라인 구축을 위한 Amazon Managed Workflow for Apache Airflow - 유다니엘 A...
아름답고 유연한 데이터 파이프라인 구축을 위한 Amazon Managed Workflow for Apache Airflow - 유다니엘 A...아름답고 유연한 데이터 파이프라인 구축을 위한 Amazon Managed Workflow for Apache Airflow - 유다니엘 A...
아름답고 유연한 데이터 파이프라인 구축을 위한 Amazon Managed Workflow for Apache Airflow - 유다니엘 A...
 
UNYOUG - APEX 19.2 New Features
UNYOUG - APEX 19.2 New FeaturesUNYOUG - APEX 19.2 New Features
UNYOUG - APEX 19.2 New Features
 
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
Spark 의 핵심은 무엇인가? RDD! (RDD paper review)
 
Common issues with Apache Kafka® Producer
Common issues with Apache Kafka® ProducerCommon issues with Apache Kafka® Producer
Common issues with Apache Kafka® Producer
 
Spring Boot Actuator
Spring Boot ActuatorSpring Boot Actuator
Spring Boot Actuator
 
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark ApplicationsTop 5 Mistakes to Avoid When Writing Apache Spark Applications
Top 5 Mistakes to Avoid When Writing Apache Spark Applications
 

Similar to Hashidays London 2017 - Evolving your Infrastructure with Terraform By Nicki Watt

Similar to Hashidays London 2017 - Evolving your Infrastructure with Terraform By Nicki Watt (20)

Declarative & workflow based infrastructure with Terraform
Declarative & workflow based infrastructure with TerraformDeclarative & workflow based infrastructure with Terraform
Declarative & workflow based infrastructure with Terraform
 
OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
 
London HUG 12/4
London HUG 12/4London HUG 12/4
London HUG 12/4
 
TIAD : Automating the modern datacenter
TIAD : Automating the modern datacenterTIAD : Automating the modern datacenter
TIAD : Automating the modern datacenter
 
Living the Nomadic life - Nic Jackson
Living the Nomadic life - Nic JacksonLiving the Nomadic life - Nic Jackson
Living the Nomadic life - Nic Jackson
 
Nomad Multi-Cloud
Nomad Multi-CloudNomad Multi-Cloud
Nomad Multi-Cloud
 
Terraform in deployment pipeline
Terraform in deployment pipelineTerraform in deployment pipeline
Terraform in deployment pipeline
 
Atmosphere Conference 2015: Taming the Modern Datacenter
Atmosphere Conference 2015: Taming the Modern DatacenterAtmosphere Conference 2015: Taming the Modern Datacenter
Atmosphere Conference 2015: Taming the Modern Datacenter
 
How containers helped a SaaS startup be developed and go live
How containers helped a SaaS startup be developed and go liveHow containers helped a SaaS startup be developed and go live
How containers helped a SaaS startup be developed and go live
 
Aprovisionamiento multi-proveedor con Terraform - Plain Concepts DevOps day
Aprovisionamiento multi-proveedor con Terraform  - Plain Concepts DevOps dayAprovisionamiento multi-proveedor con Terraform  - Plain Concepts DevOps day
Aprovisionamiento multi-proveedor con Terraform - Plain Concepts DevOps day
 
Erik Skytthe - Monitoring Mesos, Docker, Containers with Zabbix | ZabConf2016
Erik Skytthe - Monitoring Mesos, Docker, Containers with Zabbix | ZabConf2016Erik Skytthe - Monitoring Mesos, Docker, Containers with Zabbix | ZabConf2016
Erik Skytthe - Monitoring Mesos, Docker, Containers with Zabbix | ZabConf2016
 
Delivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and DockerDelivering Go.CD with Terraform and Docker
Delivering Go.CD with Terraform and Docker
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices A Hands-on Introduction on Terraform Best Concepts and Best Practices
A Hands-on Introduction on Terraform Best Concepts and Best Practices
 
MongoDB World 2019: Creating a Self-healing MongoDB Replica Set on GCP Comput...
MongoDB World 2019: Creating a Self-healing MongoDB Replica Set on GCP Comput...MongoDB World 2019: Creating a Self-healing MongoDB Replica Set on GCP Comput...
MongoDB World 2019: Creating a Self-healing MongoDB Replica Set on GCP Comput...
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
 
Fullstack conf 2017 - Basic dev pipeline end-to-end
Fullstack conf 2017 - Basic dev pipeline end-to-endFullstack conf 2017 - Basic dev pipeline end-to-end
Fullstack conf 2017 - Basic dev pipeline end-to-end
 
Terraform 0.9 + good practices
Terraform 0.9 + good practicesTerraform 0.9 + good practices
Terraform 0.9 + good practices
 
Terraform: Cloud Configuration Management (WTC/IPC'16)
Terraform: Cloud Configuration Management (WTC/IPC'16)Terraform: Cloud Configuration Management (WTC/IPC'16)
Terraform: Cloud Configuration Management (WTC/IPC'16)
 
Deploying Plone and Volto, the Hard Way
Deploying Plone and Volto, the Hard WayDeploying Plone and Volto, the Hard Way
Deploying Plone and Volto, the Hard Way
 

More from OpenCredo

Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto FernandezKafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
OpenCredo
 
MuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
MuCon 2017: A not So(A) Trivial Question by Tareq AbedrabboMuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
MuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
OpenCredo
 
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
OpenCredo
 

More from OpenCredo (20)

Webinar - Design Thinking for Platform Engineering
Webinar - Design Thinking for Platform EngineeringWebinar - Design Thinking for Platform Engineering
Webinar - Design Thinking for Platform Engineering
 
MuCon 2019: Exploring Your Microservices Architecture Through Network Science...
MuCon 2019: Exploring Your Microservices Architecture Through Network Science...MuCon 2019: Exploring Your Microservices Architecture Through Network Science...
MuCon 2019: Exploring Your Microservices Architecture Through Network Science...
 
Goto Chicago; Journeys To Cloud Native Architecture: Sun, Sea And Emergencies...
Goto Chicago; Journeys To Cloud Native Architecture: Sun, Sea And Emergencies...Goto Chicago; Journeys To Cloud Native Architecture: Sun, Sea And Emergencies...
Goto Chicago; Journeys To Cloud Native Architecture: Sun, Sea And Emergencies...
 
Mucon 2018: Heuristics for Identifying Microservice Boundaries By Erich Eichi...
Mucon 2018: Heuristics for Identifying Microservice Boundaries By Erich Eichi...Mucon 2018: Heuristics for Identifying Microservice Boundaries By Erich Eichi...
Mucon 2018: Heuristics for Identifying Microservice Boundaries By Erich Eichi...
 
Journeys To Cloud Native Architecture: Sun, Sea And Emergencies - Nicki Watt
Journeys To Cloud Native Architecture: Sun, Sea And Emergencies - Nicki WattJourneys To Cloud Native Architecture: Sun, Sea And Emergencies - Nicki Watt
Journeys To Cloud Native Architecture: Sun, Sea And Emergencies - Nicki Watt
 
Machine Learning Game Changer for IT - Maartens Lourens
Machine Learning Game Changer for IT - Maartens LourensMachine Learning Game Changer for IT - Maartens Lourens
Machine Learning Game Changer for IT - Maartens Lourens
 
Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto FernandezKafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
Kafka Summit 2018: A Journey Building Kafka Connectors - Pegerto Fernandez
 
MuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
MuCon 2017: A not So(A) Trivial Question by Tareq AbedrabboMuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
MuCon 2017: A not So(A) Trivial Question by Tareq Abedrabbo
 
DevOpsCon Berlin 2017: Project Management from Stone Age to DevOps By Antoni...
DevOpsCon Berlin 2017: Project Management from Stone Age to DevOps  By Antoni...DevOpsCon Berlin 2017: Project Management from Stone Age to DevOps  By Antoni...
DevOpsCon Berlin 2017: Project Management from Stone Age to DevOps By Antoni...
 
Succeeding with DevOps Transformation - Rafal Gancarz
Succeeding with DevOps Transformation - Rafal GancarzSucceeding with DevOps Transformation - Rafal Gancarz
Succeeding with DevOps Transformation - Rafal Gancarz
 
Progscon 2017: Serverless Architectures - Rafal Gancarz
Progscon 2017: Serverless Architectures - Rafal GancarzProgscon 2017: Serverless Architectures - Rafal Gancarz
Progscon 2017: Serverless Architectures - Rafal Gancarz
 
QCON London 2017 - Monitoring Serverless Architectures by Rafal Gancarz
QCON London 2017 - Monitoring Serverless Architectures by Rafal GancarzQCON London 2017 - Monitoring Serverless Architectures by Rafal Gancarz
QCON London 2017 - Monitoring Serverless Architectures by Rafal Gancarz
 
Voxxed Bristol 2017 - From C to Q, one event at a time: Event Sourcing illust...
Voxxed Bristol 2017 - From C to Q, one event at a time: Event Sourcing illust...Voxxed Bristol 2017 - From C to Q, one event at a time: Event Sourcing illust...
Voxxed Bristol 2017 - From C to Q, one event at a time: Event Sourcing illust...
 
London Hashicorp Meetup #8 - Testing Programmable Infrastructure By Matt Long
London Hashicorp Meetup #8 -  Testing Programmable Infrastructure By Matt LongLondon Hashicorp Meetup #8 -  Testing Programmable Infrastructure By Matt Long
London Hashicorp Meetup #8 - Testing Programmable Infrastructure By Matt Long
 
ServerlessConf: Serverless for the Enterprise - Rafal Gancarz
ServerlessConf: Serverless for the Enterprise - Rafal GancarzServerlessConf: Serverless for the Enterprise - Rafal Gancarz
ServerlessConf: Serverless for the Enterprise - Rafal Gancarz
 
O'Reilly 2016: "Continuous Delivery with Containers: The Trials and Tribulati...
O'Reilly 2016: "Continuous Delivery with Containers: The Trials and Tribulati...O'Reilly 2016: "Continuous Delivery with Containers: The Trials and Tribulati...
O'Reilly 2016: "Continuous Delivery with Containers: The Trials and Tribulati...
 
Haufe #msaday - The Actor model: an alternative approach to concurrency By Lo...
Haufe #msaday - The Actor model: an alternative approach to concurrency By Lo...Haufe #msaday - The Actor model: an alternative approach to concurrency By Lo...
Haufe #msaday - The Actor model: an alternative approach to concurrency By Lo...
 
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
Haufe #msaday - Seven More Deadly Sins of Microservices by Daniel Bryant
 
Haufe #msaday - Building a Microservice Ecosystem by Daniel Bryant
Haufe #msaday - Building a Microservice Ecosystem by Daniel Bryant Haufe #msaday - Building a Microservice Ecosystem by Daniel Bryant
Haufe #msaday - Building a Microservice Ecosystem by Daniel Bryant
 
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
A Visual Introduction to Event Sourcing and CQRS by Lorenzo NicoraA Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
 

Recently uploaded

Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
panagenda
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Recently uploaded (20)

Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoft
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 

Hashidays London 2017 - Evolving your Infrastructure with Terraform By Nicki Watt

  • 1. EVOLVING YOUR INFRASTRUCTURE WITH TERRAFORM Nicki Watt - CTO
 @techiewatt 12-06-2017
  • 2. ABOUT ME / OPENCREDO ▸OpenCredo CTO ▸Premiere HashiCorp partner ▸Hands on software development consultancy ▸Cloud, Data Engineering, DevSecOps 2
  • 3. AGENDA ▸Evolving your Terraform ▸Orchestrating your Terraform ▸Conclusion 3
  • 4. 4 Evolving your Terraform
 (a journey from a client’s perspective)
  • 5. 6 Example: E-Commerce System in AWS
 (delivered as a Micro-services architecture) 

  • 7. 8 public DMZ & Bastion Box k8s clusterSample System 
 Simple 
 Kubernetes (K8S) 
 Environment database (RDS)
  • 8. 9 Pass #1 - In the beginning …
  • 9. 10 https://github.com/mycompany/myproject terraform.tf ## Test VPC resource "aws_vpc" "test" { cidr_block = "10.0.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bastion resource "aws_instance" “test_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . } 
 - terraform-prod.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate
  • 10. 11 We must to go to production this week …
  • 11. terraform.tf ## Test VPC resource "aws_vpc" "test" { cidr_block = "10.0.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bastion resource "aws_instance" “test_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . } ## Prod VPC resource "aws_vpc" "prod" { cidr_block = "172.16.0.0/21" enable_dns_support = true enable_dns_hostnames = true } 12 https://github.com/mycompany/myproject 
 - terraform-prod.tfbkp
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate
  • 12. terraform-test.tf ## Test VPC resource "aws_vpc" "test" { cidr_block = "10.0.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bast-ion resource "aws_instance" “test_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . } ## Prod VPC resource "aws_vpc" "prod" { cidr_block = "10.0.0.3/24" enable_dns_support = true enable_dns_hostnames = true } 13 https://github.com/mycompany/myproject terraform-prod.tf ## Prod VPC resource "aws_vpc" "prod" { cidr_block = "172.16.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bastion resource "aws_instance" “prod_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . 
 - terraform-prod.tf
 - terraform-test.tf
 - terraform.tfvars
 - terraform.tfstate
  • 13. 14 Need an upgraded CIDR range in TEST …
  • 14. 15 
 - terraform-prod.tfbkp
 - terraform-test.tf
 - terraform.tfvars
 - terraform.tfstate https://github.com/mycompany/myproject terraform-test.tf ## Test VPC resource "aws_vpc" "test" { cidr_block = "10.0.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bast-ion resource "aws_instance" “test_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . } ## Prod VPC resource "aws_vpc" "prod" { cidr_block = "10.0.0.3/24" enable_dns_support = true enable_dns_hostnames = true } terraform-prod.tf ## Prod VPC resource "aws_vpc" "prod" { cidr_block = "172.16.0.0/21" enable_dns_support = true enable_dns_hostnames = true } ## Staging Bastion resource "aws_instance" “prod_bastion" { ami = "ami-7abd5555" instance_type = "t2.large" . . . 15
  • 15. 16 Help! I seem to have deleted production
  • 17. ▸Single state file ▸Single definition file ▸Hard coded config ▸Local state Terralith: Characteristics 18
  • 18. ▸Can’t manage environments separately ▸Config not that intuitive 
 (big ball of mud) ▸Maintenance challenge: Duplicate Defs (not DRY) Terralith - Pain points 19
  • 21. ▸Envs - Separate State Management ▸Multiple Terraform Definition Files ▸Better Use of Variables Multi Terralith: Characteristics 22
  • 22. + test
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate 23 https://github.com/mycompany/myproject networks.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = true enable_dns_hostnames = true } vms.tf resource "aws_instance" "node" { count = "${var.node_count}" ami = "ami-7abd5555" instance_type = “${var.vm_type}” . . . } + prod
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate
  • 23. 24 https://github.com/mycompany/myproject networks.tf resource "aws_vpc" "core" { cidr_block = “${var.cidr}” enable_dns_support = true enable_dns_hostnames = true } vms.tf resource "aws_instance" "node" { count = "${var.node_count}" ami = "ami-7abd5555" instance_type = “${var.vm_type}” . . . } + test
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate + prod
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate
  • 24. + test
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate 25 https://github.com/mycompany/myproject networks.tf resource "aws_vpc" "core" { cidr_block = “${var.cidr}” enable_dns_support = true enable_dns_hostnames = true } vms.tf resource "aws_instance" "node" { count = "${var.node_count}" ami = "ami-7abd5555" instance_type = “${var.vm_type}” . . . } + prod
 - networks.tf
 - vms.tf
 - terraform.tfvars
 - terraform.tfstate
  • 25. Terralith - (recap) 26 ▸Can’t manage environments separately
 ▸Config not that intuitive 
 (big ball of mud) ▸Maintenance challenge: Duplicate Defs (not DRY)
  • 26. Multi Terralith 27 ▸Manage environment separately
 (separate state files per env) ▸More intuitive configuration
 (multiple files) ▸Maintenance challenge: Duplicate Defs (not DRY) ✅ "
  • 29. ▸Reusable modules ▸Envs compose themselves from modules ▸Restructuring of repo 30 Terramod: Characteristics
  • 31. 32 database core k8s-cluster - VPC
 - All Subnets
 - Core Routing & Gateways
 - Bastion Host (OpenVPN server) - Instances
 - Security Groups - Amazon RDS
 - DB Subnet Group
  • 32. 33 + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 https://github.com/mycompany/myproject separate env management & module defs
  • 33. 34 + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 https://github.com/mycompany/myproject define logical components as re-usable modules
  • 34. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 35 https://github.com/mycompany/myproject core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } resource "aws_subnet" "private" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.priv_cidr}" ... }
  • 35. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 36 https://github.com/mycompany/myproject core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } resource "aws_subnet" "private" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.priv_cidr}" ... } input.tf variable "cidr" {} variable "dns” {} variable "dnsh" {} variable "dmz_cidr" {} variable "priv_cidr" {} ...
  • 36. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 37 https://github.com/mycompany/myproject core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } resource "aws_subnet" "private" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.priv_cidr}" ... } input.tf variable "cidr" {} variable "dns” {} variable "dnsh" {} variable "dmz_cidr" {} variable "priv_cidr" {} ... output.tf output "priv_subnet_id" { value ="${aws_subnet.private.id}" } ...
  • 37. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 38 https://github.com/mycompany/myproject defines the contract of the module
  • 38. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 39 https://github.com/mycompany/myproject terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = 
 "${module.core.priv_subnet_id}" }
  • 39. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 40 https://github.com/mycompany/myproject terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = 
 "${module.core.priv_subnet_id}" }
  • 40. + envs/[test|prod]
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 41 https://github.com/mycompany/myproject terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = 
 "${module.core.priv_subnet_id}" }
  • 41. ▸Manage environment separately
 (separate state files per env) ▸More intuitive configuration
 (multiple files) ▸Maintenance challenge: Duplicate Defs (not DRY) Multi Terralith 42 ✅ "
  • 42. ▸Manage environment separately
 (separate state files per env) ▸Intuitive configuration
 (reusable modules) ▸Reduced Duplicate Definitions 
 (DRYer) Terramod 43 ✅ " ✅
  • 44. 45 Alan Chia (https://commons.wikimedia.org/wiki/File:Lego_Color_Bricks.jpg) terramod Marcos Leal (https://commons.wikimedia.org/wiki/File:Army_(2995294027).jpg) n
  • 45. ▸Nested modules ▸base modules
 (low level infrastructure specific) ▸logical modules
 (system specific) ▸Sometimes dedicated module repo 46 Terramod : Characteristics n
  • 46. 47 https://github.com/mycompany/myproject + envs
 + modules
 + project
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - k8s.tf
 - output.tf
 logical (system specific) modules
  • 47. 48 https://github.com/mycompany/myproject + envs
 + modules
 + common
 + aws
 + network
 + vpc
 + pub_subnet
 + priv_subnet
 + comps
 + instance
 + db-instance
 + envs
 + modules
 + project
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - k8s.tf
 - output.tf
 logical (system specific) modules base (infra specific) modules
  • 48. 49 https://github.com/mycompany/myproject + envs
 + modules
 + common
 + aws
 + network
 + vpc
 + pub_subnet
 + priv_subnet
 + comps
 + instance
 + db-instance
 + envs
 + modules
 + project
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - k8s.tf
 - output.tf
 modules/project/core/core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... }
  • 49. modules/project/core/core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } + envs
 + modules
 + project
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - k8s.tf
 - output.tf
 50 https://github.com/mycompany/myproject
  • 50. modules/project/core/core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } + envs
 + modules
 + common
 + aws
 + network
 + vpc
 + pub_subnet
 + priv_subnet
 + comps
 + instance
 + db-instance
 50 https://github.com/mycompany/myproject modules/project/core/core.tf module "vpc" { source = "../../common/aws/net/vpc" cidr = "${var.vpc_cidr}" } module "dmz-subnet" { source = "../../common/aws/net/pub-subnet" vpc_id = "${module.vpc.vpc_id}" subnet_cidrs = [ “${var.dmz_cidr}” ] } module "priv-subnet" { source = "../../common/aws/net/priv-subnet" vpc_id = "${module.vpc.vpc_id}" subnet_cidrs = [ “${var.priv_cidr}” ]
  • 51. + envs
 + modules
 + common
 + aws
 + network
 + vpc
 + pub_subnet
 + priv_subnet
 + comps
 + instance
 + db-instance
 modules/project/core/core.tf resource "aws_vpc" "core" { cidr_block = "${var.cidr}" enable_dns_support = "${var.dns}" enable_dns_hostnames = "${var.dnsh}" } resource "aws_subnet" "dmz" { vpc_id = "${aws_vpc.core.id}" cidr_block = "${var.dmz_cidr}" map_public_ip_on_launch = 1 ... } 51 https://github.com/mycompany/myproject modules/project/core/core.tf module "vpc" { source = "../../common/aws/net/vpc" cidr = "${var.vpc_cidr}" } module "dmz-subnet" { source = "../../common/aws/net/pub-subnet" vpc_id = "${module.vpc.vpc_id}" subnet_cidrs = [ “${var.dmz_cidr}” ] } module "priv-subnet" { source = "../../common/aws/net/priv-subnet" vpc_id = "${module.vpc.vpc_id}" subnet_cidrs = [ “${var.priv_cidr}” ] BUT … Issue #953 - Support the count parameter for modules
  • 52. ▸Manage environment separately
 (separate state files per env) ▸Intuitive configuration
 (reusable modules) ▸Reduced Duplicate Definitions 
 (DRYer) Terramod (recap) 52 ✅ " ✅
  • 53. ▸Manage environment separately
 (separate state files per env) ▸Intuitive configuration
 (reusable modules) ▸Reduced Duplicate Definitions further 
 (as DRY as possible given restrictions) Terramod 53 n ✅ " ✅
  • 55. 55 Maintenance required …
 - Make bastion box smaller -
  • 56. + envs/prod
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 56 terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" bastion_flav = "${var.bastion_flav}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" node_flavour = "${var.bastion_flav}" } terraform.tfvars vpc_cidr = “10.0.0.0/21” bastion_flav = “r4.large” node_flavour = “m4.4xlarge”
  • 57. + envs/prod
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 57 terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" bastion_flav = "${var.bastion_flav}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" node_flavour = "${var.bastion_flav}" } terraform.tfvars vpc_cidr = “10.0.0.0/21” bastion_flav = “m4.large” node_flavour = “m4.4xlarge”
  • 58. + envs/prod
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 58 terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" bastion_flav = "${var.bastion_flav}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" node_flavour = "${var.bastion_flav}" } terraform.tfvars vpc_cidr = “10.0.0.0/21” bastion_flav = “m4.large” node_flavour = “m4.4xlarge”
  • 59. 59 Help! I seem to be rebuilding the K8S cluster!
  • 60. + envs/prod
 - config.tf
 - terraform.tf
 - terraform.tfvars
 - terraform.tfstate + modules
 + core
 - input.tf
 - core.tf
 - output.tf
 + k8s-cluster
 - input.tf
 - dns.tf
 - vms.tf
 - output.tf
 60 terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" bastion_flav = "${var.bastion_flav}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" node_flavour = "${var.bastion_flav}" } terraform.tfvars vpc_cidr = “10.0.0.0/21” bastion_flav = “m4.large” node_flavour = “m4.4xlarge” OOPS! Typo
  • 61. ▸Can’t manage logical parts of our infrastructure independently Next set of pain! 61
  • 64. ▸ Independent management of logical comps ▸ Isolates & Reduces Risk ▸ Aids with Multi Team Setups ▸Distributed (Remote State) ▸Requires additional orchestration effort Terraservices - Characteristics 64
  • 65. 65 database core k8s-cluster - VPC
 - All Subnets
 - Core Routing & Gateways
 - Bastion Host (OpenVPN server) - Instances
 - Security Groups - Amazon RDS
 - DB Subnet Group
  • 66. + envs
 + test
 
 - ...
 - ...
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 - ...
 - ...
 + k8s-cluster
 - ... 66 - terraform.tfstate
 - terraform.tfvars
 - xxx.tf Terraservices - Repo Structure From
  • 67. 67 - terraform.tfstate
 - terraform.tfvars
 - xxx.tf To + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... Terraservices - Repo Structure
  • 68. + envs
 + test
 
 - ...
 - ...
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 - ...
 - ...
 + k8s-cluster
 - ... 68 envs/test/terraform.tf module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" dmz_cidr = "${var.dmz_cidr}" priv_cidr = "${var.priv_cidr}" } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = 
 "${module.core.priv_subnet_id}" } Terramod - Connecting (recap) From
  • 69. 69 + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... envs/test/core/terraform.tf # Optional but explicit! (Needs 0.9+) terraform { backend "local" { path = "terraform.tfstate" } } module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" envs/test/core/outputs.tf output "priv_subnet_id" { value ="${module.core.priv_subnet_id}" } Terraservices - Connecting To
  • 70. 70 + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... envs/test/core/terraform.tf # Optional but explicit! (Needs 0.9+) terraform { backend "local" { path = "terraform.tfstate" } } module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" envs/test/core/outputs.tf output "priv_subnet_id" { value ="${aws_subnet.private.id}" } envs/test/k8s-cluster/terraform.tf data "terraform_remote_state" "core" { backend = "local" config { path = “../core/terraform.tfstate" } } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = “${data.terraform_remote_ state.core.priv_subnet_id}" }
 } Terraservices - Connecting To
  • 71. Terraservices - Characteristics 71 ▸ Independent management of logical comps ▸ Isolates & Reduces Risk ▸ Aids with Multi Team Setups ▸Distributed (Remote State) ▸Requires additional orchestration effort
  • 72. 72 + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... envs/test/core/terraform.tf # Optional but explicit! (Needs 0.9+) terraform { backend "local" { path = "terraform.tfstate" } } module "core" { source = "../../modules/core" cidr = "${var.vpc_cidr}" envs/test/core/outputs.tf output "priv_subnet_id" { value ="${module.core.priv_subnet_id}" } Terraservices - Distributed (Remote State) From
  • 73. 73 + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... envs/test/core/terraform.tf # Optional but explicit! (Needs 0.9+) terraform { backend "s3" { region = "eu-west-1" bucket = "myco/myproj/test" key = "core/terraform.tfstate" encrypt = "true" } } envs/test/core/outputs.tf output "priv_subnet_id" { value ="${module.core.priv_subnet_id}" } Terraservices - Distributed (Remote State) To
  • 74. 74 + envs
 + test
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ... envs/test/core/terraform.tf # Optional but explicit! (Needs 0.9+) terraform { backend "s3" { region = "eu-west-1" bucket = "myco/myproj/test" key = "core/terraform.tfstate" encrypt = "true" } } envs/test/core/outputs.tf output "priv_subnet_id" { value ="${module.core.priv_subnet_id}" } Terraservices - Distributed (Remote State) To envs/test/k8s-cluster/terraform.tf data "terraform_remote_state" "core" { backend = "s3" config { region = "eu-west-1" bucket = "myco/myproj/test" key = "core/terraform.tfstate" encrypt = "true" } } module "k8s-cluster" { source = "../../modules/k8s-cluster" num_nodes = "${var.k8s_nodes}" priv_subnet = “${data.terraform_remote_ state.core.priv_subnet_id}"
  • 75. 75 + envs
 + test|prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + modules
 + common
 + aws
 + network
 + vpc
 Terraservices - Repo Isolation (Optional) https://github.com/myco/myproj From
  • 76. 76 + envs
 + test|prod
 + core
 - ...
 + database
 - ...
 + k8s-cluster
 - ...
 
 + modules
 + common
 + aws
 + network
 + vpc
 Terraservices - Repo Isolation (Optional) https://github.com/myco/myproj https://github.com/myco/myproj-core https://github.com/myco/myproj-db https://github.com/myco/myproj-k8s https://github.com/myco/tf-modcomm To
  • 77. Terraservices - Characteristics 77 ▸ Independent management of logical comps ▸ Isolates & Reduces Risk ▸ Aids with Multi Team Setups ▸Distributed (Remote State) ▸Requires additional orchestration effort
  • 85. 85 Orchestration System Laptops, Local State 
 & READMEs Remote State
  • 86. 86 Orchestration System Laptops, Local State 
 & READMEs Remote State
  • 87. 87 Orchestration System Laptops, Remote State, 
 Shared Services,
 & READMEs
  • 88. 88 Orchestration System Who builds the infrastructure that builds the infrastructure ?
  • 89. 89 Orchestration System Jenkins, Remote State,
 Custom Scripts, 
 Shared Services,
 & READMEs
  • 92. 92 It’s not just about the structure of the code … You also need to evolve your supporting orchestration system & processes
  • 95. 95 EVOLVING YOUR TERRAFORM SETUP ▸Terralith ▸Multi Terralith - Envs: Independent management ▸Terramod ▸Terramod - Modules : Maintainability & Reuse ▸Terraservices - Logical Components: Independent
 management n
  • 96. 96 EVOLVING YOUR TERRAFORM SETUP ▸Terralith ▸Multi Terralith - Envs: Independent management ▸Terramod ▸Terramod - Modules : Maintainability & Reuse ▸Terraservices - Logical Components: Independent
 management n
  • 97. 97 EVOLVING YOUR TERRAFORM SETUP ▸Terralith ▸Multi Terralith - Envs: Independent management ▸Terramod ▸Terramod - Modules : Maintainability & Reuse ▸Terraservices - Logical Components: Independent
 management n
  • 98. 98 EVOLVING YOUR TERRAFORM SETUP ▸Terralith ▸Multi Terralith - Envs: Independent management ▸Terramod ▸Terramod - Modules : Maintainability & Reuse ▸Terraservices - Logical Components: Independent
 management n
  • 99. 99 EVOLVING YOUR TERRAFORM SETUP ▸Terralith ▸Multi Terralith - Envs: Independent management ▸Terramod ▸Terramod - Modules : Maintainability & Reuse ▸Terraservices - Logical Components: Independent
 management n
  • 100. 100 Also need to consider how to evolve the management & orchestration of Terraform