参考:terraform官网
一、什么是terraform?
Terraform是一个开源的基础架构即代码的工具。通过这个工具,可以把我们的基础架构通过代码的形式进行维护。
二、什么是基础架构?
应用运行所需要的的底层设备,可以是物理设备或者虚拟设备。现在基本上都使用的虚拟设备,虚拟设备基本上都是在云上。
比如说,一个公司需要部署一个网站,我们选择了AWS,那么我们需要在aws上创建我们的infrastructure,也就是虚拟机,有了这个infrastructure,才可以去创建我们的网站。
那么这个infrastructure怎么去创建呢?当然,我们可以通过去aws页面上通过鼠标点的方式去创建一台VM,也可以用同样的方式创建其他的资源,比如网络地址,网络策略,数据库,DNS等等。这些都可以通过手动方式去操作,但是手动的操作就不具备可维护性,比如说如果有一天我们需要把这些操作重新搞一遍,就不可能重新去手动重复做这些操作。如果我们能将这些手动的过程代码化,那么我们就可以很快地把我们的infrastructure创建好。
有同学会问,现在很多云厂商,比如AWS,阿里云等,不是提供了自己的API吗?我们可以通过API去创建这些资源。
但是每家云厂商的API是不一样的,如果我们需要管理多套云下面的资源,就需要维护多套代码。实际上Terraform就是帮我们解决这个问题的。Terraform在这个API之上又做了一层,把具体调用各个云厂商的API给屏蔽掉了,它去做具体的调用。我们可以认为Terraform是一种编程语言也好,配置的描述工具也好,我们只需要学习Terraform,就可以很方便地管理云上的API
三、安装Terraform
参考:https://developer.hashicorp.com/terraform/intro
windows电脑安装
下载windows对应的二进制文件,放到C盘/windows/system32目录下面
#下载:
https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_windows_amd64.zip
#放到C盘/windows/system32目录下面
#用cmd或者powershell测试
PS C:\Users\xxxx> terraform --help
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
......
vscode安装HashCorp Terraform插件
该插件可以让terraform代码高亮显示,如下图所示

Linux安装(ubuntu)
#安装必要的软件包
~]# sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
#导入gpg密钥
~]# curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
#添加terraform软件源
~]# echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee
#安装terraform
~]# apt update
~]# apt install terraform
#验证安装成功
~]# terraform --help
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
......
#开启命令行自动补全
~]# terraform -install-autocomplete
四、编写一个最简单的terraform代码
操作AWS,阿里云等云厂商的资源可能需要花钱,这里就选用免费的docker来演示下。
该代码是使用nginx镜像部署一个nginx容器,需要docker环境,需要提前准备好。
#创建一个目录存放项目代码
~]# mkdir learn-terraform-docker-container
~]# cd learn-terraform-docker-container
learn-terraform-docker-container]# cat main.tf
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "demo"
ports {
internal = 80
external = 8000
}
}
这段代码是要做什么?
-
required_providers:需要操作的provider,比如docker,或者aws,或者google cloud等。你可以认为它是一个API或者软件包等(是不是跟python导入模块有点像?)
required_providers { docker = { source = "kreuzwerker/docker" version = "~> 3.0.1" } }
-
resource:资源。指具体要操作的对象。这里定义了两个资源
-
docker_image资源:需要一个nginx镜像
resource "docker_image" "nginx" { name = "nginx" keep_locally = false }
-
docker_container资源:container的名字,使用的镜像,映射的端口等
resource "docker_container" "nginx" { image = docker_image.nginx.image_id name = "demo" ports { internal = 80 external = 8000 } }
-
五、如何使用上面这段代码
格式化和校验
#如果代码缩进不统一,可以让terraform帮我们调整代码缩进等
#如果代码缩进没有问题,那么执行该命令不会有输出
learn-terraform-docker-container]# terraform fmt
main.tf
#校验配置文件是否有效
learn-terraform-docker-container]# terraform validate
Success! The configuration is valid.
初始化项目
terraform init
:初始化项目。它会根据配置文件下载我们需要的provider plugins,让terraform与docker进行交互。这一步会连接github下载,需要保证网络顺通。
learn-terraform-docker-container]# HTTPS_PROXY="192.168.66.1:10811" terraform init
Initializing the backend...
Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 3.0.1"...
- Installing kreuzwerker/docker v3.0.2...
- Installed kreuzwerker/docker v3.0.2 (self-signed, key ID BD080C4571C6104C)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
展示当前配置的计划
有点像k8s集群创建资源的--dry-run
,它会检测tf配置文件,告诉我们哪些资源做了变更,但是不做创建或更新资源的动作
- docker_container.nginx将会被创建,docker_image.nginx将会被创建
learn-terraform-docker-container]# terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "tutorial"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60
+ ports {
+ external = 8000
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ image_id = (known after apply)
+ keep_locally = false
+ name = "nginx"
+ repo_digest = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply"
now.
创建基础设施
terraform apply
:根据tf配置文件创建基础设施,并生成一个terraform.tfstate
文件,用于保存基础设施的状态。
- 中间会有一个交互式操作,需要我们输入yes确认,才会创建相关的资源
- 执行apply后会先把
trraform plan
的内容打印一遍,然后让我们输出yes确认,然后才开始创建资源。 - 先是创建了docker_image.nginx资源,然后创建了docker_container.nginx资源
learn-terraform-docker-container]# terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# docker_container.nginx will be created
+ resource "docker_container" "nginx" {
+ attach = false
+ bridge = (known after apply)
+ command = (known after apply)
+ container_logs = (known after apply)
+ container_read_refresh_timeout_milliseconds = 15000
+ entrypoint = (known after apply)
+ env = (known after apply)
+ exit_code = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ image = (known after apply)
+ init = (known after apply)
+ ipc_mode = (known after apply)
+ log_driver = (known after apply)
+ logs = false
+ must_run = true
+ name = "tutorial"
+ network_data = (known after apply)
+ read_only = false
+ remove_volumes = true
+ restart = "no"
+ rm = false
+ runtime = (known after apply)
+ security_opts = (known after apply)
+ shm_size = (known after apply)
+ start = true
+ stdin_open = false
+ stop_signal = (known after apply)
+ stop_timeout = (known after apply)
+ tty = false
+ wait = false
+ wait_timeout = 60
+ ports {
+ external = 8000
+ internal = 80
+ ip = "0.0.0.0"
+ protocol = "tcp"
}
}
# docker_image.nginx will be created
+ resource "docker_image" "nginx" {
+ id = (known after apply)
+ image_id = (known after apply)
+ keep_locally = false
+ name = "nginx"
+ repo_digest = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
docker_image.nginx: Creating...
docker_image.nginx: Still creating... [10s elapsed]
docker_image.nginx: Creation complete after 16s [id=sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 1s [id=981b7c660d041ed1c296a82fcb7db0927b244cb0ce00024863ad2be420a11436]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
查看镜像和创建的容器
learn-terraform-docker-container]# docker image ls nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 904b8cb13b93 2 weeks ago 142MB
learn-terraform-docker-container]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
981b7c660d04 904b8cb13b93 "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8000->80/tcp tutorial
terraform目录结构
看下面第六节
检查管理基础设施状态
- terraform show:检查当前infrastructure的状态
- terraform state list:列出项目状态下的资源
learn-terraform-docker-container]# terraform show
# docker_container.nginx:
resource "docker_container" "nginx" {
attach = false
command = [
"nginx",
"-g",
"daemon off;",
]
container_read_refresh_timeout_milliseconds = 15000
cpu_shares = 0
entrypoint = [
"/docker-entrypoint.sh",
]
env = []
hostname = "c6e5cbe2abef"
id = "c6e5cbe2abef2285b4a658ec21cdeebf35c4b57ddb3b6542bd9ba137841ff0d2"
image = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8"
init = false
ipc_mode = "private"
log_driver = "json-file"
logs = false
max_retry_count = 0
memory = 0
memory_swap = 0
must_run = true
name = "tutorial"
network_data = [
{
gateway = "172.17.0.1"
global_ipv6_address = ""
global_ipv6_prefix_length = 0
ip_address = "172.17.0.2"
ip_prefix_length = 16
ipv6_gateway = ""
mac_address = "02:42:ac:11:00:02"
network_name = "bridge"
},
]
network_mode = "default"
privileged = false
publish_all_ports = false
read_only = false
remove_volumes = true
restart = "no"
rm = false
runtime = "runc"
security_opts = []
shm_size = 64
start = true
stdin_open = false
stop_signal = "SIGQUIT"
stop_timeout = 0
tty = false
wait = false
wait_timeout = 60
ports {
external = 8000
internal = 80
ip = "0.0.0.0"
protocol = "tcp"
}
}
# docker_image.nginx:
resource "docker_image" "nginx" {
id = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx"
image_id = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8"
keep_locally = false
name = "nginx"
repo_digest = "nginx@sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce1d4b4f55a5c2ef2"
}
learn-terraform-docker-container]# terraform state list
docker_container.nginx
docker_image.nginx
修改terraform文件
也就是修改infrastructure配置。我这里将容器的名字由tutorial改为demo,然后再次执行terraform apply
可以看到terraform执行的详细过程。首先是把terraform plan的内容打印了一下(需要add一个资源,destroy一个资源),然后输入yes确认;然后是真正的操作过程(先把docker_container.nginx资源destroy,然后create一个新的docker_container.nginx资源)
learn-terraform-docker-container]# terraform apply
docker_image.nginx: Refreshing state... [id=sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx]
docker_container.nginx: Refreshing state... [id=c6e5cbe2abef2285b4a658ec21cdeebf35c4b57ddb3b6542bd9ba137841ff0d2]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# docker_container.nginx must be replaced
-/+ resource "docker_container" "nginx" {
+ bridge = (known after apply)
~ command = [
- "nginx",
- "-g",
- "daemon off;",
] -> (known after apply)
+ container_logs = (known after apply)
- cpu_shares = 0 -> null
- dns = [] -> null
- dns_opts = [] -> null
- dns_search = [] -> null
~ entrypoint = [
- "/docker-entrypoint.sh",
] -> (known after apply)
~ env = [] -> (known after apply)
+ exit_code = (known after apply)
- group_add = [] -> null
~ hostname = "c6e5cbe2abef" -> (known after apply)
~ id = "c6e5cbe2abef2285b4a658ec21cdeebf35c4b57ddb3b6542bd9ba137841ff0d2" -> (known after apply)
~ init = false -> (known after apply)
~ ipc_mode = "private" -> (known after apply)
~ log_driver = "json-file" -> (known after apply)
- log_opts = {} -> null
- max_retry_count = 0 -> null
- memory = 0 -> null
- memory_swap = 0 -> null
~ name = "tutorial" -> "demo" # forces replacement
~ network_data = [
- {
- gateway = "172.17.0.1"
- global_ipv6_address = ""
- global_ipv6_prefix_length = 0
- ip_address = "172.17.0.2"
- ip_prefix_length = 16
- ipv6_gateway = ""
- mac_address = "02:42:ac:11:00:02"
- network_name = "bridge"
},
] -> (known after apply)
- network_mode = "default" -> null
- privileged = false -> null
- publish_all_ports = false -> null
~ runtime = "runc" -> (known after apply)
~ security_opts = [] -> (known after apply)
~ shm_size = 64 -> (known after apply)
~ stop_signal = "SIGQUIT" -> (known after apply)
~ stop_timeout = 0 -> (known after apply)
- storage_opts = {} -> null
- sysctls = {} -> null
- tmpfs = {} -> null
# (14 unchanged attributes hidden)
# (1 unchanged block hidden)
}
Plan: 1 to add, 0 to change, 1 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
docker_container.nginx: Destroying... [id=c6e5cbe2abef2285b4a658ec21cdeebf35c4b57ddb3b6542bd9ba137841ff0d2]
docker_container.nginx: Destruction complete after 0s
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 0s [id=de2f6494366e68a392c5ffb99386c05677d553799cedd6d03114088ff871102c]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
销毁操作
terraform destroy:销毁tf配置文件里面定义的infrastructure
在main.tf文件里面docker_image资源里面有一个keep_locally = false
的内容,表示销毁该资源的时候不保留本地镜像

learn-terraform-docker-container]# terraform destroy
docker_image.nginx: Refreshing state... [id=sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx]
docker_container.nginx: Refreshing state... [id=de2f6494366e68a392c5ffb99386c05677d553799cedd6d03114088ff871102c]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# docker_container.nginx will be destroyed
- resource "docker_container" "nginx" {
- attach = false -> null
- command = [
- "nginx",
- "-g",
- "daemon off;",
] -> null
- container_read_refresh_timeout_milliseconds = 15000 -> null
- cpu_shares = 0 -> null
- dns = [] -> null
- dns_opts = [] -> null
- dns_search = [] -> null
- entrypoint = [
- "/docker-entrypoint.sh",
] -> null
- env = [] -> null
- group_add = [] -> null
- hostname = "de2f6494366e" -> null
- id = "de2f6494366e68a392c5ffb99386c05677d553799cedd6d03114088ff871102c" -> null
- image = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8" -> null
- init = false -> null
- ipc_mode = "private" -> null
- log_driver = "json-file" -> null
- log_opts = {} -> null
- logs = false -> null
- max_retry_count = 0 -> null
- memory = 0 -> null
- memory_swap = 0 -> null
- must_run = true -> null
- name = "demo" -> null
- network_data = [
- {
- gateway = "172.17.0.1"
- global_ipv6_address = ""
- global_ipv6_prefix_length = 0
- ip_address = "172.17.0.2"
- ip_prefix_length = 16
- ipv6_gateway = ""
- mac_address = "02:42:ac:11:00:02"
- network_name = "bridge"
},
] -> null
- network_mode = "default" -> null
- privileged = false -> null
- publish_all_ports = false -> null
- read_only = false -> null
- remove_volumes = true -> null
- restart = "no" -> null
- rm = false -> null
- runtime = "runc" -> null
- security_opts = [] -> null
- shm_size = 64 -> null
- start = true -> null
- stdin_open = false -> null
- stop_signal = "SIGQUIT" -> null
- stop_timeout = 0 -> null
- storage_opts = {} -> null
- sysctls = {} -> null
- tmpfs = {} -> null
- tty = false -> null
- wait = false -> null
- wait_timeout = 60 -> null
- ports {
- external = 8000 -> null
- internal = 80 -> null
- ip = "0.0.0.0" -> null
- protocol = "tcp" -> null
}
}
# docker_image.nginx will be destroyed
- resource "docker_image" "nginx" {
- id = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx" -> null
- image_id = "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8" -> null
- keep_locally = false -> null
- name = "nginx" -> null
- repo_digest = "nginx@sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce1d4b4f55a5c2ef2" -> null
}
Plan: 0 to add, 0 to change, 2 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
docker_container.nginx: Destroying... [id=de2f6494366e68a392c5ffb99386c05677d553799cedd6d03114088ff871102c]
docker_container.nginx: Destruction complete after 0s
docker_image.nginx: Destroying... [id=sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx]
docker_image.nginx: Destruction complete after 0s
Destroy complete! Resources: 2 destroyed.
执行销毁操作后,tfstate状态文件也就没有资源的状态了
learn-terraform-docker-container]# cat terraform.tfstate
{
"version": 4,
"terraform_version": "1.4.2",
"serial": 26,
"lineage": "c07a4276-9059-92fb-f905-095f2c5a9e2d",
"outputs": {},
"resources": [],
"check_results": null
}
六、terraform目录结构
可以看到,我们刚才只创建了一个main.tf
文件,现在又多出了好几个文件
.terraform
目录:存放docker的provider,版本是v3.0.2.terraform.lock.hcl
:存放docker provider版本相关的信息,锁定docker provider的版本(是不是有点像nodejs里面的package-lock.json文件)- terraform.tfstate:状态文件。 这个文件是非常非常重要的 ,它表示的是当前infrastructure的状态是什么。这个文件就确保了我们在部署infrastructure有个一致性了。当我们再次执行terraform apply的时候,他说不会有任何变化的,因为它会读取tfstate文件,发现已经满足我们的要求了,就不会再执行。
- 如果不小心把tfstate文件删除了,再次执行terraform apply它就会执行拉取镜像和创建容器的操作。
- 每次执行terraform apply,它都会对原来的tfstate文件做一个backup,也就是下面的terraform.tfstate.backup文件
learn-terraform-docker-container]# tree . -a
.
├── main.tf
├── .terraform
│ └── providers
│ └── registry.terraform.io
│ └── kreuzwerker
│ └── docker
│ └── 3.0.2
│ └── linux_amd64
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ └── terraform-provider-docker_v3.0.2
├── .terraform.lock.hcl
├── terraform.tfstate
└── terraform.tfstate.backup
7 directories, 8 files
learn-terraform-docker-container]# cat .terraform.lock.hcl
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/kreuzwerker/docker" {
version = "3.0.2"
constraints = "~> 3.0.1"
hashes = [
"h1:cT2ccWOtlfKYBUE60/v2/4Q6Stk1KYTNnhxSck+VPlU=",
"zh:15b0a2b2b563d8d40f62f83057d91acb02cd0096f207488d8b4298a59203d64f",
"zh:23d919de139f7cd5ebfd2ff1b94e6d9913f0977fcfc2ca02e1573be53e269f95",
"zh:38081b3fe317c7e9555b2aaad325ad3fa516a886d2dfa8605ae6a809c1072138",
"zh:4a9c5065b178082f79ad8160243369c185214d874ff5048556d48d3edd03c4da",
"zh:5438ef6afe057945f28bce43d76c4401254073de01a774760169ac1058830ac2",
"zh:60b7fadc287166e5c9873dfe53a7976d98244979e0ab66428ea0dea1ebf33e06",
"zh:61c5ec1cb94e4c4a4fb1e4a24576d5f39a955f09afb17dab982de62b70a9bdd1",
"zh:a38fe9016ace5f911ab00c88e64b156ebbbbfb72a51a44da3c13d442cd214710",
"zh:c2c4d2b1fd9ebb291c57f524b3bf9d0994ff3e815c0cd9c9bcb87166dc687005",
"zh:d567bb8ce483ab2cf0602e07eae57027a1a53994aba470fa76095912a505533d",
"zh:e83bf05ab6a19dd8c43547ce9a8a511f8c331a124d11ac64687c764ab9d5a792",
"zh:e90c934b5cd65516fbcc454c89a150bfa726e7cf1fe749790c7480bbeb19d387",
"zh:f05f167d2eaf913045d8e7b88c13757e3cf595dd5cd333057fdafc7c4b7fed62",
"zh:fcc9c1cea5ce85e8bcb593862e699a881bd36dffd29e2e367f82d15368659c3d",
]
}
learn-terraform-docker-container]# cat terraform.tfstate
{
"version": 4,
"terraform_version": "1.4.2",
"serial": 13,
"lineage": "c07a4276-9059-92fb-f905-095f2c5a9e2d",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "docker_container",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 2,
"attributes": {
"attach": false,
"bridge": "",
"capabilities": [],
"cgroupns_mode": null,
"command": [
"nginx",
"-g",
"daemon off;"
],
"container_logs": null,
"container_read_refresh_timeout_milliseconds": 15000,
"cpu_set": "",
"cpu_shares": 0,
"destroy_grace_seconds": null,
"devices": [],
"dns": null,
"dns_opts": null,
"dns_search": null,
"domainname": "",
"entrypoint": [
"/docker-entrypoint.sh"
],
"env": [],
"exit_code": null,
"gpus": null,
"group_add": null,
"healthcheck": null,
"host": [],
"hostname": "143d04de74e8",
"id": "143d04de74e840acc6bca210767606ffac4352539e7e7fbc81c12aa4a52057a2",
"image": "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8",
"init": false,
"ipc_mode": "private",
"labels": [],
"log_driver": "json-file",
"log_opts": null,
"logs": false,
"max_retry_count": 0,
"memory": 0,
"memory_swap": 0,
"mounts": [],
"must_run": true,
"name": "demo",
"network_data": [
{
"gateway": "172.17.0.1",
"global_ipv6_address": "",
"global_ipv6_prefix_length": 0,
"ip_address": "172.17.0.2",
"ip_prefix_length": 16,
"ipv6_gateway": "",
"mac_address": "02:42:ac:11:00:02",
"network_name": "bridge"
}
],
"network_mode": "default",
"networks_advanced": [],
"pid_mode": "",
"ports": [
{
"external": 8000,
"internal": 80,
"ip": "0.0.0.0",
"protocol": "tcp"
}
],
"privileged": false,
"publish_all_ports": false,
"read_only": false,
"remove_volumes": true,
"restart": "no",
"rm": false,
"runtime": "runc",
"security_opts": [],
"shm_size": 64,
"start": true,
"stdin_open": false,
"stop_signal": "SIGQUIT",
"stop_timeout": 0,
"storage_opts": null,
"sysctls": null,
"tmpfs": null,
"tty": false,
"ulimit": [],
"upload": [],
"user": "",
"userns_mode": "",
"volumes": [],
"wait": false,
"wait_timeout": 60,
"working_dir": ""
},
"sensitive_attributes": [],
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjIifQ==",
"dependencies": [
"docker_image.nginx"
]
}
]
},
{
"mode": "managed",
"type": "docker_image",
"name": "nginx",
"provider": "provider[\"registry.terraform.io/kreuzwerker/docker\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"build": [],
"force_remove": null,
"id": "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8nginx",
"image_id": "sha256:904b8cb13b932e23230836850610fa45dce9eb0650d5618c2b1487c2a4f577b8",
"keep_locally": false,
"name": "nginx",
"platform": null,
"pull_triggers": null,
"repo_digest": "nginx@sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce1d4b4f55a5c2ef2",
"triggers": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
],
"check_results": null
}