This week I learned two valuable aspects of Terraform I did not know.
The first is Terraform State Import. While I use terraform state to list and show state and even remove state, I was unaware you could import from a created AWS resource. It’s not actually an argument to the “terraform state” syntax, instead its “terraform import” and likely why I do not see it when I look at terraform state syntax.
% terraform state Usage: terraform [global options] state[options] [args] This command has subcommands for advanced state management. These subcommands can be used to slice and dice the Terraform state. This is sometimes necessary in advanced cases. For your safety, all state management commands that modify the state create a timestamped backup of the state prior to making modifications. The structure and output of the commands is specifically tailored to work well with the common Unix utilities such as grep, awk, etc. We recommend using those tools to perform more advanced state tasks. 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
I am not an expert in Terraform, and looking at the command help output shown above did not give me reference to look elsewhere, but just reading the manual can help you to learn a new feature. If you do not know a product, reading documentation and examples can be an ideal way to get started in a self-paced way.
The second is Meta-Arguments. I use lifecycle, and to be honest I have learned and forgotten about count. Count was something I was able to use to solve a very nasty cross-region kinesis stream issue, reminding me of a syntax I had since forgotten. Using coalesce and conditional expressions (aka ternary operator) can help in modules, for example.
resource "aws_rds_cluster" "demo" { ... global_cluster_identifier = var.has_global_cluster ? local.global_cluster_identifier : "" master_username = var.has_global_cluster ? "" : var.master_username db_cluster_parameter_group_name = coalesce(var.db_cluster_parameter_group_name , local.db_cluster_parameter_group_name) ...
However to stop the creation of the object completely, use count.
resource "aws_???" "demo_???" { count = var.filter_condition ? 1 : 0 ...
And just when I thought I’d read about Meta-Arguments, I hit a new never before seen problem. Now if I’d read the summary resources page about Meta-Arguments, and looked the very next section I would have been able to likely solve this new error without having to RTFM a second time.
module.?.?.aws_rds_cluster.default: Still creating... [1h59m53s elapsed] Error: Error waiting for RDS Cluster state to be "available": timeout while waiting for state to become 'available' (last state: 'creating', timeout: 2h0m0s) on .terraform/modules/?/main.tf line 306, in resource "aws_rds_cluster" "default": 306: resource "aws_rds_cluster" "default" {
I did not know there was a 2 hour timeout, and I did not know you can change that with
timeouts { create = "4h" delete = "4h" } }
On a number of occasions I have found documentation to not be complete or accurate online. If you find this, then submit a request to get it fixed, must sources include a link at the bottom to recommend improvements. I have had good success with submitting improvements to the AWS documentation.