it locks all versions for us.
terraform plan -out=plan1 # we define our plan as plan1
terraform apply plan1 # execute our plan wihtout confirmation- we cna store our state file in our local machine, remote state ( blob or terraform cloud)
terraform show -json #it shows our state file with json format
terraform state list #list the resources that we created- we use console for some testing issues
terraform console # we can enter console
docker_container.nginx_container.ip_address #we can reach container ip address.- it gives us some information about our resources and we can consume them in another resource
output "IP-Address" {
value = docker_container.nginx_container.ip_address
description = "IP address of container"
}
output "container-name" {
value = docker_container.nginx_container.name
}terraform output #with that command we can see all outputsjoin (seperator, list)
join ", ", ["foo", "bar", "baz"]
join(":", [docker_container.nginx_container.ip_address, docker_container.nginx_container.ports[0].external]) #we can join ip address and ports then use it in outputresource "random_string" "random" {
length = 16
special = true
override_special = "/@ÂŁ$"
}terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
}
}
}
provider "docker" {}
resource "docker_image" "nginx_image" {
name = "nginx:alpine"
}
resource "random_string" "random" {
length = 4
special = false
upper = false
}
resource "random_string" "random2" {
length = 4
special = false
upper = false
}
resource "docker_container" "nginx_container" {
name = join("-", ["nginx", random_string.random.result])
image = docker_image.nginx_image.latest
ports {
internal = "80"
# external = "80"
}
}
resource "docker_container" "nginx_container2" {
name = join("-", ["nginx", random_string.random2.result])
image = docker_image.nginx_image.latest
ports {
internal = "80"
# external = "80"
}
}
output "IP-Address" {
value = join(":", [docker_container.nginx_container.ip_address, docker_container.nginx_container.ports[0].external])
description = "IP address of container"
}
output "container-name" {
value = docker_container.nginx_container.name
}
output "container-name-2" {
value = docker_container.nginx_container2.name
}
resource "random_string" "random" {
count = 2
length = 4
special = false
upper = false
}
resource "docker_image" "nginx_image" {
name = "nginx:alpine"
}
resource "random_string" "random" {
count = 2
length = 4
special = false
upper = false
}
resource "docker_container" "nginx_container" {
count = 2
name = join("-", ["nginx", random_string.random[count.index].result])
image = docker_image.nginx_image.latest
ports {
internal = "80"
# external = "80"
}
}
output "IP-Address" {
value = join(":", [docker_container.nginx_container[0].ip_address, docker_container.nginx_container[0].ports[0].external])
description = "IP address of container"
}
output "container-name" {
value = docker_container.nginx_container[0].name
}
output "container2-name" {
value = docker_container.nginx_container[1].name
}output "container-name" {
value = docker_container.nginx_container[*].name
}
output "IP-Address" {
value = [for i in docker_container.nginx_container[*] : join(":", [i.ip_address], i.ports[*]["external"])]
description = "IP address of container"
}
output "container-name" {
value = docker_container.nginx_container[*].name
}
[for i in docker_container.nginx_container[*] : join(":", [i.ip_address], [i.ports[0]["external"]])]
[for i in docker_container.nginx_container[*] : join(":", [i.ip_address], i.ports[*]["external"])]- If we want to force some resource to reload and reinstall, then we just use tainting
terraform taint random_string.random[0] #just tainted a resource
terraform untaint random_string.random[0] #just untainted a resourceterraform apply -lock=false #we just unlock the state
# default is lock=true-
if we have more resources out of state, we can include them to our state file with import command
-
first we add resources to our .tf file, then use terraform import <resource_id> command
terraform import docker_container.nginx_container-2 $(docker inspect -f {{.ID}} nginx-yrwl)- The terraform refresh command reads the current settings from all managed remote objects and updates the Terraform state to match.
-This won't modify your real remote objects, but it will modify the the Terraform state.
terraform refresh
terraform refresh -target random_string.random #just targeted specific resources- if someone delete our resources that we keep them state file, and we want to update our state file. In thias case we can use terraform state rm command. just remove deleted resources from state file.
terraform state rm random_string.random[1]terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
}
}
}
provider "docker" {}
variable "ext_port" {
type = number
default = 80
}
variable "int_port" {
type = number
default = 80
}
variable "container_count" {
type = number
default = 1
}
resource "docker_image" "nginx_image" {
name = "nginx:alpine"
}
resource "random_string" "random" {
count = 1
length = 4
special = false
upper = false
}
resource "docker_container" "nginx_container" {
count = var.container_count
name = join("-", ["nginx", random_string.random[count.index].result])
image = docker_image.nginx_image.latest
ports {
internal = var.int_port
external = var.ext_port
}
}
output "IP-Address" {
value = [for i in docker_container.nginx_container[*] : join(":", [i.ip_address], i.ports[*]["external"])]
description = "IP address of container"
}
output "container-name" {
value = docker_container.nginx_container[*].name
}variable "ext_port" {
type = number
default = 80
validation {
condition = var.ext_port == 80
error_message = "The External port must be 80."
}
}
variable "int_port" {
type = number
default = 80
validation {
condition = var.int_port <= 65535 && var.int_port > 0
error_message = "The internal port must be in the valid port range 0 - 65535."
}
}Error: Invalid value for variable
on main.tf line 11:
11: variable "ext_port" {
The External port must be 80.
This was checked by the validation rule at main.tf:14,3-13.- we just define variables in variables.tf file and put sensitive variables in to .tfvars file
variable "ext_port" {
type = number
sensitive = true
}Terraform loads variables in the following order, with later sources taking precedence over earlier ones:
- Environment variables
- The terraform.tfvars file, if present.
- The terraform.tfvars.json file, if present.
- Any _.auto.tfvars or _.auto.tfvars.json files, processed in lexical order of their filenames.
- Any -var and -var-file options on the command line, in the order they are provided. (This includes variables set by a Terraform Cloud workspace.)
terraform plan --var-file=centraf.tf #we just used anothter .tfvars file
terraform plan -var ext_port=1980 # we just mention our vars on cliresource "null_resource" "dockervol" {
provisioner "local-exec" {
command = "mkdir nginxvol/ || true && sudo chown -R 1000:1000 nginxvol/"
}
}locals {
container_count = length(var.ext_port)
}
resource "docker_container" "nginx_container" {
count = local.container_count
name = join("-", ["nginx", random_string.random[count.index].result])
image = docker_image.nginx_image.latest
ports {
internal = var.int_port
external = var.ext_port[count.index]
}
volumes {
container_path = "/data"
host_path = "/home/mustafa/Terraform/terraform-docker/nginxvol"
}
}max([10,20,30]...) > 30
variable "ext_port" {
type = list(any)
validation {
condition = max(var.ext_port...) <= 65535 && min(var.ext_port...) > 0
error_message = "The internal port must be in the valid port range 0 - 65535."
}
}resource "docker_container" "nginx_container" {
count = local.container_count
name = join("-", ["nginx", random_string.random[count.index].result])
image = docker_image.nginx_image.latest
ports {
internal = var.int_port
external = var.ext_port[count.index]
}
volumes {
container_path = "/data"
host_path = "${path.cwd}/nginxvol"
}
}variable "image" {
type = map(any)
description = "image for container"
default = {
dev = "nginx:latest"
prod = "nginx:alpine"
}
}
resource "docker_image" "nginx_image" {
name = lookup(var.image, var.env)
}- we can also use workspace as a variable inside of resources and locals
locals {
container_count = length(lookup(var.ext_port, terraform.workspace))
}
resource "docker_container" "nginx_container" {
count = local.container_count
name = join("-", ["nginx", terraform.workspace, random_string.random[count.index].result])
image = docker_image.nginx_image.latest
ports {
internal = var.int_port
external = lookup(var.ext_port, terraform.workspace)[count.index]
}
volumes {
container_path = "/data"
host_path = "${path.cwd}/nginxvol"
}
}
terraform workspace new dev # create a new called dev workspace and switch to it.
terraform workspace show #show the current working workspace
terraform workspace list # list all workspace
terraform select workspace dev # switch the dev ws.
sudo apt install graphviz # install graph program
terraform graph | dot -Tpdf > graph-plan.pdf # we can save our graph in a pdf file
terraform graph -type=plan=destroy | dot -Tpdf > graph-destroy.pdf # we just create a destroy graph- show seperated list values into a one list.
output "IP-Address" {
value = flatten(module.container[*].ip-address)
description = "IP address of container."
}
resource "docker_volume" "container_volume" {
name = "${var.name_in}-volume"
lifecycle {
prevent_destroy = true
}
}
terraform destroy -target=module.container[0].docker_container.nginx_container #destroy just specific resourcelocals {
deployment = {
nginx = {
image = var.image["nginx"][terraform.workspace]
}
influxdb = {
image = var.image["influxdb"][terraform.workspace]
}
}
}
module "image" {
source = "./image"
for_each = local.deployment
image_in = each.value.image
}public_cidrs = [for i in range(2, 255, 2): cidrsubnet("10.123.0.0/16", 8, i)]
private_cidrs = [for i in range(1, 255, 2): cidrsubnet("10.123.0.0/16", 8, i)]resource "aws_security_group" "mustafa_sg" {
for_each = var.security_groups
name = each.value.name
description = each.value.description
vpc_id = aws_vpc.mustafa_vpc.id
dynamic "ingress" {
for_each = each.value.ingress
content {
from_port = ingress.value.from
to_port = ingress.value.to
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}