Snake
- Why Snake?
- It's Snake!
- Easy, but requires:
Naming is Hard
- Define locals in locals
- Use a local with local.name
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define resources in resources?
Naming is Hard
- Define locals in locals
- Use a local with local.name
Define resources in resources
- Define each resource with resource
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with resource.name?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
Use things in resources with resource.name
- Use things in resources with resource.type.name?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
Use things in resources with resource.name
Use things in resources with resource.type.name
- Use things in resources with type.name
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each input with input?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
Define each input with input
- Define each input with variable
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each input with variable
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with variable.name?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
Use an input variable with variable.name
- Use an input variable with var.name
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with var.name
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with var.name
- Define each output with output?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with var.name
- Define each output with output 🎉
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with var.name
- Define each output with output 🎉
- Define each data source with data?
Naming is Hard
- Define locals in locals
- Use a local with local.name
- Define each resource with resource
- Use things in resources with type.name
- Define each "input variable" with variable
- Use an input variable with var.name
- Define each output with output 🎉
- Define each data source with data 🎉
Naming is Hard
- Define each module with module?
Naming is Hard
Define each module with module
- Define a module by creating a directory 😲
Naming is Hard
- Define a module by creating a directory
- Use a module by ...?
Naming is Hard
- Define a module by creating a directory
- Use a module by adding a module block
Naming is Hard
- Define a module by creating a directory
- Use a module by adding a module block
- Use a module output with module.module_name.output_name?
Naming is Hard
- Define a module by creating a directory
- Use a module by adding a module block
- Use a module output with module.module_name.output_name 🎉
The Cheating
# Python3
# ... setup PyGame...
while 1:
# ... get input and append to inp ...
subprocess.run("terraform apply -var inp=%s" % inp)
subprocess.run("terraform output text")
# .. convert text output to graphics
The Cheating
terraform apply -var inp=.
terraform apply -var inp=.r
terraform apply -var inp=.r.
terraform apply -var inp=.r..
terraform apply -var inp=.r..l
terraform apply -var inp=.r..lu
# ... etc. ...
The OKish Code
# snake.tf
variable "inp" {
type = string
}
output "text" {
value = module.view.text
}
The OKish Code
# snake.tf
resource "random_integer" "apple" {
min = 1
max = var.size - 1
count = 2
}
The OKish Code
# snake.tf
locals {
initial_model = {
size = var.size
snake = [[4, 5], [4, 6], [4, 7], [4, 8]]
apple = [
random_integer.apple[0].result,
random_integer.apple[1].result
]
dir = "u"
dead = false
}
}
The OKish Code
# snake.tf
module "update" {
source = "./modules/update"
model = local.initial_model
inp = var.inp
}
The OKish Code
# snake.tf
module "view" {
source = "./modules/view"
model = module.update.value
}
The OKish Code
# view.tf
grid = [for y in local.ys: [for x in local.xs:
(
var.model.dead &&
[x, y] == var.model.snake[0]
) ?
"d" :
(
x == 0
|| x == var.model.size - 1
|| y == 0
|| y == var.model.size - 1
) ?
"#" :
(x == var.model.apple[0] && y == var.model.apple[1]) ?
"a" :
(contains(var.model.snake, [x, y])) ?
"o" :
" "
]]
The OKish Code
# update_one.tf
dead = (
var.model.dead ||
(
contains(var.model.snake, local.new_head) ||
local.new_head[0] < 1 ||
local.new_head[0] >= var.model.size - 1 ||
local.new_head[1] < 1 ||
local.new_head[1] >= var.model.size - 1
)
)
The Bad Code
# update.tf
# I am very sorry for what I have done
module "u_000" {
source = "../update_one"
model = var.model
inp = var.inp
idx = 0
}
module "u_001" {
source = "../update_one"
model = module.u_000.value
inp = var.inp
idx = 1
}
# ... repeated 50 times
Thoughts
- Pros:
- Same tool across multiple cloud environments
- Idempotent
- Cons:
- Totally different resources for each cloud provider
- Weird, inconsistent syntax
- Once you get the concepts, it mostly works