Terraform 1.0.1の新機能使ってみた

2021.06.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

先日、TerraformのVersion 1.0.1がGAになりました。新機能をチェックしてみたいと思います。

とはいっても、今回の新機能は1つだけ、かつ細かいアップデートのようです。JSONアウトプットにsensitive属性情報が追加されました。

JSONアウトプット?

plan

通常terraform planを実行すると、applyした場合にどのような変更が発生するか(=plan結果)が出力されますよね。この時-out=<PATH>というオプションを追加すると、画面にplan結果を出力する代わりに、<PATH>位置にplan結果をバイナリファイルとして出力してくれます。バイナリなのでそのままファイルを見ることはできません。見るときはterraform show <FILE>というコマンドを使います。

$ terraform show plan-binary                 

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:

  # aws_vpc.tokyo-vpc will be created
  + resource "aws_vpc" "tokyo-vpc" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "10.0.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = (known after apply)
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name" = (sensitive)
        }
      + tags_all                         = {
          + "Name" = "test"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

terraform planを普通に使う(=-outオプション使わない)場合のような出力内容になります。

このとき、 terraform show-jsonオプションを追加することもできます。すると出力がJSONになります。(以下出力例では、terraform show -jsonそのままだと改行やインデントが入ってなくて見にくいのでjqをかましています)

$ terraform show -json plan-binary | jq .
{
  "format_version": "0.2",
  "terraform_version": "1.0.1",
  "variables": {
    "vpc-name": {
      "value": "test"
    }
  },
  "planned_values": {
    "root_module": {
      "resources": [
        {
          "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",
          "type": "aws_vpc",
          "name": "tokyo-vpc",
          "provider_name": "registry.terraform.io/hashicorp/aws",
          "schema_version": 1,
          "values": {
            "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "10.0.0.0/16",
            "enable_dns_support": true,
            "instance_tenancy": "default",
            "tags": {
              "Name": "test"
            },
            "tags_all": {
              "Name": "test"
            }
          },
          "sensitive_values": {
            "tags": {
              "Name": true
            },
            "tags_all": {}
          }
        }
      ]
    }
  },
  "resource_changes": [
    {
      "address": "aws_vpc.tokyo-vpc",
      "mode": "managed",
      "type": "aws_vpc",
      "name": "tokyo-vpc",
      "provider_name": "registry.terraform.io/hashicorp/aws",
      "change": {
        "actions": [
          "create"
        ],
        "before": null,
        "after": {
          "assign_generated_ipv6_cidr_block": false,
          "cidr_block": "10.0.0.0/16",
          "enable_dns_support": true,
          "instance_tenancy": "default",
          "tags": {
            "Name": "test"
          },
          "tags_all": {
            "Name": "test"
          }
        },
        "after_unknown": {
          "arn": true,
          "default_network_acl_id": true,
          "default_route_table_id": true,
          "default_security_group_id": true,
          "dhcp_options_id": true,
          "enable_classiclink": true,
          "enable_classiclink_dns_support": true,
          "enable_dns_hostnames": true,
          "id": true,
          "ipv6_association_id": true,
          "ipv6_cidr_block": true,
          "main_route_table_id": true,
          "owner_id": true,
          "tags": {},
          "tags_all": {}
        },
        "before_sensitive": false,
        "after_sensitive": {
          "tags": {
            "Name": true
          },
          "tags_all": {}
        }
      }
    }
  ],
  "configuration": {
    "provider_config": {
      "aws": {
        "name": "aws",
        "version_constraint": "3.43.0",
        "expressions": {
          "region": {
            "constant_value": "ap-northeast-1"
          }
        }
      }
    },
    "root_module": {
      "resources": [
        {
          "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",
          "type": "aws_vpc",
          "name": "tokyo-vpc",
          "provider_config_key": "aws",
          "expressions": {
            "cidr_block": {
              "constant_value": "10.0.0.0/16"
            },
            "tags": {
              "references": [
                "var.vpc-name"
              ]
            }
          },
          "schema_version": 1
        }
      ],
      "variables": {
        "vpc-name": {
          "default": "test",
          "sensitive": true
        }
      }
    }
  }
}

ちなみにこのバイナリファイルですが、terraform apply <FILE>とapplyに食わせることでバイナリファイルの内容を元にapplyが走ります。Terraformの実行を自動化したいときに使うと役立つそうです。

state

Steteファイルも上記plan結果と同様にterraform showで内容確認できます。Stateの内容を出力したいときは引数にファイル名は不要です。

$ terraform show   
# aws_vpc.tokyo-vpc:
resource "aws_vpc" "tokyo-vpc" {
    arn                              = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0a8c82393a77eb14e"
    assign_generated_ipv6_cidr_block = false
    cidr_block                       = "10.0.0.0/16"
    default_network_acl_id           = "acl-0207ae0c05d285d52"
    default_route_table_id           = "rtb-0f6ab10583067f23e"
    default_security_group_id        = "sg-08ae9ab50d841f4f6"
    dhcp_options_id                  = "dopt-6f460008"
    enable_classiclink               = false
    enable_classiclink_dns_support   = false
    enable_dns_hostnames             = false
    enable_dns_support               = true
    id                               = "vpc-0a8c82393a77eb14e"
    instance_tenancy                 = "default"
    ipv6_association_id              = ""
    ipv6_cidr_block                  = ""
    main_route_table_id              = "rtb-0f6ab10583067f23e"
    owner_id                         = "123456789012"
    tags                             = {
        "Name" = (sensitive)
    }
    tags_all                         = {
        "Name" = "test"
    }
}

で、こちらもJSON形式の出力が可能です。

$ terraform show -json | jq .
{
  "format_version": "0.2",
  "terraform_version": "1.0.0",
  "values": {
    "root_module": {
      "resources": [
        {
          "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",
          "type": "aws_vpc",
          "name": "tokyo-vpc",
          "provider_name": "registry.terraform.io/hashicorp/aws",
          "schema_version": 1,
          "values": {
            "arn": "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0a8c82393a77eb14e",
            "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "10.0.0.0/16",
            "default_network_acl_id": "acl-0207ae0c05d285d52",
            "default_route_table_id": "rtb-0f6ab10583067f23e",
            "default_security_group_id": "sg-08ae9ab50d841f4f6",
            "dhcp_options_id": "dopt-6f460008",
            "enable_classiclink": false,
            "enable_classiclink_dns_support": false,
            "enable_dns_hostnames": false,
            "enable_dns_support": true,
            "id": "vpc-0a8c82393a77eb14e",
            "instance_tenancy": "default",
            "ipv6_association_id": "",
            "ipv6_cidr_block": "",
            "main_route_table_id": "rtb-0f6ab10583067f23e",
            "owner_id": "123456789012",
            "tags": {
              "Name": "test"
            },
            "tags_all": {
              "Name": "test"
            }
          },
          "sensitive_values": {
            "tags": {
              "Name": true
            },
            "tags_all": {}
          }
        }
      ]
    }
  }
}

Sensitive?

Sensitive属性は、変数やOutputの引数として指定できるものです。sensitive = trueとつけると、その変数やOutputの値や、それを参照している値がterraform planterraform applyなどの出力時に隠蔽化されます。出力内容が何らかのロギングシステムやVCS(バージョンコントールシステム)などに記録されるようになっていて、パスワードなどの機密情報が記録されるのを阻止したい場合に役立ちます。(ただし、この機能を使ってもStateファイルに変数値が書き込まれる点は変わりませんので、依然としてStateファイルの扱いには気をつけましょう。)

具体的なアップデート内容

前置きが長くなりましたが、1.0.1の新機能「JSONアウトプットにsensitive属性情報が追加」というのは、terraform show -jsonでplanやstateの情報を出力したときに、何がsensitive属性を持っているのかが表示されるようになったということです。

例として、以下のようにVPCのNameタグ値にsensitive属性をつけた変数を参照するようなコードを書きました。planの方はこのコードでVPCを作成するときのもの、stateは作成後のstateを確認したときのものです。

resource "aws_vpc" "tokyo-vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = var.vpc-name
  }
}
variable "vpc-name" {
  default = "test"
  sensitive = true
}

plan結果の違い(左=v1.0.0,右=v1.0.1)

$ diff 100output.json 101output.json -y
{                                                               {
  "format_version": "0.1",                                    |   "format_version": "0.2",
  "terraform_version": "1.0.0",                               |   "terraform_version": "1.0.1",
  "variables": {                                                  "variables": {
    "vpc-name": {                                                   "vpc-name": {
      "value": "test"                                                 "value": "test"
    }                                                               }
  },                                                              },
  "planned_values": {                                             "planned_values": {
    "root_module": {                                                "root_module": {
      "resources": [                                                  "resources": [
        {                                                               {
          "address": "aws_vpc.tokyo-vpc",                                 "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",                                              "mode": "managed",
          "type": "aws_vpc",                                              "type": "aws_vpc",
          "name": "tokyo-vpc",                                            "name": "tokyo-vpc",
          "provider_name": "registry.terraform.io/hashicorp/a             "provider_name": "registry.terraform.io/hashicorp/a
          "schema_version": 1,                                            "schema_version": 1,
          "values": {                                                     "values": {
            "assign_generated_ipv6_cidr_block": false,                      "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "10.0.0.0/16",                                    "cidr_block": "10.0.0.0/16",
            "enable_dns_support": true,                                     "enable_dns_support": true,
            "instance_tenancy": "default",                                  "instance_tenancy": "default",
            "tags": {                                                       "tags": {
              "Name": "test"                                                  "Name": "test"
            },                                                              },
            "tags_all": {                                                   "tags_all": {
              "Name": "test"                                                  "Name": "test"
            }                                                               }
                                                              >           },
                                                              >           "sensitive_values": {
                                                              >             "tags": {
                                                              >               "Name": true
                                                              >             },
                                                              >             "tags_all": {}
          }                                                               }
        }                                                               }
      ]                                                               ]
    }                                                               }
  },                                                              },
  "resource_changes": [                                           "resource_changes": [
    {                                                               {
      "address": "aws_vpc.tokyo-vpc",                                 "address": "aws_vpc.tokyo-vpc",
      "mode": "managed",                                              "mode": "managed",
      "type": "aws_vpc",                                              "type": "aws_vpc",
      "name": "tokyo-vpc",                                            "name": "tokyo-vpc",
      "provider_name": "registry.terraform.io/hashicorp/aws",         "provider_name": "registry.terraform.io/hashicorp/aws",
      "change": {                                                     "change": {
        "actions": [                                                    "actions": [
          "create"                                                        "create"
        ],                                                              ],
        "before": null,                                                 "before": null,
        "after": {                                                      "after": {
          "assign_generated_ipv6_cidr_block": false,                      "assign_generated_ipv6_cidr_block": false,
          "cidr_block": "10.0.0.0/16",                                    "cidr_block": "10.0.0.0/16",
          "enable_dns_support": true,                                     "enable_dns_support": true,
          "instance_tenancy": "default",                                  "instance_tenancy": "default",
          "tags": {                                                       "tags": {
            "Name": "test"                                                  "Name": "test"
          },                                                              },
          "tags_all": {                                                   "tags_all": {
            "Name": "test"                                                  "Name": "test"
          }                                                               }
        },                                                              },
        "after_unknown": {                                              "after_unknown": {
          "arn": true,                                                    "arn": true,
          "default_network_acl_id": true,                                 "default_network_acl_id": true,
          "default_route_table_id": true,                                 "default_route_table_id": true,
          "default_security_group_id": true,                              "default_security_group_id": true,
          "dhcp_options_id": true,                                        "dhcp_options_id": true,
          "enable_classiclink": true,                                     "enable_classiclink": true,
          "enable_classiclink_dns_support": true,                         "enable_classiclink_dns_support": true,
          "enable_dns_hostnames": true,                                   "enable_dns_hostnames": true,
          "id": true,                                                     "id": true,
          "ipv6_association_id": true,                                    "ipv6_association_id": true,
          "ipv6_cidr_block": true,                                        "ipv6_cidr_block": true,
          "main_route_table_id": true,                                    "main_route_table_id": true,
          "owner_id": true,                                               "owner_id": true,
          "tags": {},                                                     "tags": {},
          "tags_all": {}                                                  "tags_all": {}
        },                                                              },
        "before_sensitive": false,                                      "before_sensitive": false,
        "after_sensitive": {                                            "after_sensitive": {
          "tags": {                                                       "tags": {
            "Name": true                                                    "Name": true
          },                                                              },
          "tags_all": {}                                                  "tags_all": {}
        }                                                               }
      }                                                               }
    }                                                               }
  ],                                                              ],
  "configuration": {                                              "configuration": {
    "provider_config": {                                            "provider_config": {
      "aws": {                                                        "aws": {
        "name": "aws",                                                  "name": "aws",
        "version_constraint": "3.43.0",                                 "version_constraint": "3.43.0",
        "expressions": {                                                "expressions": {
          "region": {                                                     "region": {
            "constant_value": "ap-northeast-1"                              "constant_value": "ap-northeast-1"
          }                                                               }
        }                                                               }
      }                                                               }
    },                                                              },
    "root_module": {                                                "root_module": {
      "resources": [                                                  "resources": [
        {                                                               {
          "address": "aws_vpc.tokyo-vpc",                                 "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",                                              "mode": "managed",
          "type": "aws_vpc",                                              "type": "aws_vpc",
          "name": "tokyo-vpc",                                            "name": "tokyo-vpc",
          "provider_config_key": "aws",                                   "provider_config_key": "aws",
          "expressions": {                                                "expressions": {
            "cidr_block": {                                                 "cidr_block": {
              "constant_value": "10.0.0.0/16"                                 "constant_value": "10.0.0.0/16"
            },                                                              },
            "tags": {                                                       "tags": {
              "references": [                                                 "references": [
                "var.vpc-name"                                                  "var.vpc-name"
              ]                                                               ]
            }                                                               }
          },                                                              },
          "schema_version": 1                                             "schema_version": 1
        }                                                               }
      ],                                                              ],
      "variables": {                                                  "variables": {
        "vpc-name": {                                                   "vpc-name": {
          "default": "test",                                              "default": "test",
          "sensitive": true                                               "sensitive": true
        }                                                               }
      }                                                               }
    }                                                               }
  }                                                               }
}                                                               }

state結果の違い(左=v1.0.0,右=v1.0.1)

$ diff 100state.json 101state.json -y                          
{                                                               {
  "format_version": "0.1",                                    |   "format_version": "0.2",
  "terraform_version": "1.0.0",                                   "terraform_version": "1.0.0",
  "values": {                                                     "values": {
    "root_module": {                                                "root_module": {
      "resources": [                                                  "resources": [
        {                                                               {
          "address": "aws_vpc.tokyo-vpc",                                 "address": "aws_vpc.tokyo-vpc",
          "mode": "managed",                                              "mode": "managed",
          "type": "aws_vpc",                                              "type": "aws_vpc",
          "name": "tokyo-vpc",                                            "name": "tokyo-vpc",
          "provider_name": "registry.terraform.io/hashicorp/a             "provider_name": "registry.terraform.io/hashicorp/a
          "schema_version": 1,                                            "schema_version": 1,
          "values": {                                                     "values": {
            "arn": "arn:aws:ec2:ap-northeast-1:123456789012:v               "arn": "arn:aws:ec2:ap-northeast-1:123456789012:v
            "assign_generated_ipv6_cidr_block": false,                      "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "10.0.0.0/16",                                    "cidr_block": "10.0.0.0/16",
            "default_network_acl_id": "acl-0207ae0c05d285d52"               "default_network_acl_id": "acl-0207ae0c05d285d52"
            "default_route_table_id": "rtb-0f6ab10583067f23e"               "default_route_table_id": "rtb-0f6ab10583067f23e"
            "default_security_group_id": "sg-08ae9ab50d841f4f               "default_security_group_id": "sg-08ae9ab50d841f4f
            "dhcp_options_id": "dopt-6f460008",                             "dhcp_options_id": "dopt-6f460008",
            "enable_classiclink": false,                                    "enable_classiclink": false,
            "enable_classiclink_dns_support": false,                        "enable_classiclink_dns_support": false,
            "enable_dns_hostnames": false,                                  "enable_dns_hostnames": false,
            "enable_dns_support": true,                                     "enable_dns_support": true,
            "id": "vpc-0a8c82393a77eb14e",                                  "id": "vpc-0a8c82393a77eb14e",
            "instance_tenancy": "default",                                  "instance_tenancy": "default",
            "ipv6_association_id": "",                                      "ipv6_association_id": "",
            "ipv6_cidr_block": "",                                          "ipv6_cidr_block": "",
            "main_route_table_id": "rtb-0f6ab10583067f23e",                 "main_route_table_id": "rtb-0f6ab10583067f23e",
            "owner_id": "123456789012",                                     "owner_id": "123456789012",
            "tags": {                                                       "tags": {
              "Name": "test"                                                  "Name": "test"
            },                                                              },
            "tags_all": {                                                   "tags_all": {
              "Name": "test"                                                  "Name": "test"
            }                                                               }
                                                              >           },
                                                              >           "sensitive_values": {
                                                              >             "tags": {
                                                              >               "Name": true
                                                              >             },
                                                              >             "tags_all": {}
          }                                                               }
        }                                                               }
      ]                                                               ]
    }                                                               }
  }                                                               }
}                                                               }

参考情報