Terraform State management to record changes

Posted by davex on Sat, 22 Jan 2022 21:44:29 +0100

My latest and complete articles are in Pumpkin speak slowly www.pkslow.com com  , welcome to tea!

brief introduction

Terraform has been used in recent work. You can learn and record it. I hope it can help others.

Terraform series articles are as follows:

Terraform introductory tutorial, sample shows managing Docker and Kubernetes resources

Terraform plug-in Provider management, search, definition and download

Terraform State management to record changes

Terraform Module management, aggregation resource extraction and reuse

Terraform common commands

State is used by Terraform to manage infrastructure and configuration. It is the mapping of real resources and can also provide the efficiency of large-scale infrastructure platform. Its main function is to bind the relationship between remote resource platform (such as AWS) and local code configuration. To put it bluntly, it stores the status and existing appearance of various resources in the actual platform.

First, feel the State through an example

If the concept is difficult to understand, feel it through examples first.

The key configurations are as follows. For details, please refer to my code at GitHub:

provider "kubernetes" {
  config_path = "~/.kube/config"
}

module "pkslow-nginx" {
    source = "./nginx"
    namespace = "pkslow"
    applicationName = "pkslow-nginx"
    image = "nginx:1.19.5"
    replicas = 3
    nodePort = 30201
}

apply first:

$ terraform apply
module.pkslow-nginx.kubernetes_deployment.test: Creating...
module.pkslow-nginx.kubernetes_deployment.test: Creation complete after 4s [id=pkslow/pkslow-nginx]
module.pkslow-nginx.kubernetes_service.test: Creating...
module.pkslow-nginx.kubernetes_service.test: Creation complete after 0s [id=pkslow/pkslow-nginx]

It creates two resources, where a new terrain will be generated in the current directory of the project Tfstate, which is the default state file. It is a file in Json format, which stores the status of the new resources created by apply, such as name, attribute, IP, etc.

At this time, if we apply again, nothing will be generated. Because the status file is the same as the actual infrastructure and the configuration has not been changed, it can be considered that the configuration is the same as the actual and does not need to be changed:

$ terraform apply
No changes. Your infrastructure matches the configuration.

I change the NodePort to 30301, and then apply again:

$ terraform apply
Plan: 0 to add, 1 to change, 0 to destroy.

module.pkslow-nginx.kubernetes_service.test: Modifying... [id=pkslow/pkslow-nginx]
module.pkslow-nginx.kubernetes_service.test: Modifications complete after 0s [id=pkslow/pkslow-nginx]

You can see that it changes only one of the two resources.

When deleting resources through destroy, you also need to read the status file. If the status file is lost, it cannot be deleted normally.

$ mv terraform.tfstate terraform.tfstate.bak

$ terraform destroy
No changes. No objects need to be destroyed.
Either you have not created any objects yet or the existing objects were already deleted outside of Terraform.
Destroy complete! Resources: 0 destroyed.

If there is a corresponding status file, it will be deleted according to the status file:

$ terraform destroy
Plan: 0 to add, 0 to change, 2 to destroy.

module.pkslow-nginx.kubernetes_service.test: Destroying... [id=pkslow/pkslow-nginx]
module.pkslow-nginx.kubernetes_service.test: Destruction complete after 0s
module.pkslow-nginx.kubernetes_deployment.test: Destroying... [id=pkslow/pkslow-nginx]
module.pkslow-nginx.kubernetes_deployment.test: Destruction complete after 0s

View status

You can view the status through the command terrain state. The main commands are:

$ terraform state

Subcommands:
    list                List resources in the state
    mv                  Move an item in the state
    pull                Pull current state and output to stdout
    push                Update remote state from a local state file
    replace-provider    Replace provider in the state
    rm                  Remove instances from the state
    show                Show a resource in the state

The operation is as follows:

$ terraform state list
module.pkslow-nginx.kubernetes_deployment.test
module.pkslow-nginx.kubernetes_service.test

$ terraform state show module.pkslow-nginx.kubernetes_deployment.test
# module.pkslow-nginx.kubernetes_deployment.test:
......

productive practice

In production, status files are generally not saved locally, but are usually saved in cloud storage, such as etcd, gcp, oss, etc.

Such as gcs configuration:

terraform {
  backend "gcs" {
    bucket  = "tf-state-prod"
    prefix  = "terraform/state"
  }
}

Alibaba cloud oss configuration:

terraform {
  backend "oss" {
    bucket = "bucket-for-terraform-state"
    prefix   = "path/mystate"
    key   = "version-1.tfstate"
    region = "cn-beijing"
    tablestore_endpoint = "https://terraform-remote.cn-hangzhou.ots.aliyuncs.com"
    tablestore_table = "statelock"
  }
}