Terraform Enum data type
In Terraform you have access to basic data types like bool or string. Defining the data type is a good start for starting to improve the quality of your modules. However, you may want to validate that a certain string matches a list of pre-defined options, and if not, fail validation early.
Terraform, unlike Puppet, does not have a built-in Enum data type. However, you can emulate an Enum like this:
Conditional provisioner blocks in Terraform
I’ll start with a spoiler: what the title suggests is not possible. It is, however, possible to accomplish this with cloud-init and Terraform templates as described in the Multi-part cloud-init provisioning with Terraform blog post.
If you need to use SSH/WinRM provisioning, then there are various workarounds you can apply, and this article explains some of them and goes into depth into one in particular.
The first workaround is relatively clean, but is not usable in all cases, especially when working with complex modules. The idea is to have two resources, here of type aws_instance. Those resources are identical except for the provisioner blocks:
Terraform Azure resource provider registration fails
Terraform has good support for Microsoft Azure through the Terraform Azure provider and the AzureRM backend. However, you may hit a glitch when adding or importing resources if you lack permissions to register Azure resource providers:
│ Error: Error ensuring Resource Providers are registered.
|
│ Terraform automatically attempts to register the Resource Providers it supports
| to ensure it's able to provision resources.
│
│ If you don't have permission to register Resource Providers you may wish to use
| the "skip_provider_registration" flag in the Provider block to disable this
| functionality.
│
│ Please note that if you opt out of Resource Provider Registration and Terraform
| tries to provision a resource from a Resource Provider which is unregistered,
| then the error may appear misleading - for example
|
│ > API version 2019-XX-XX was not found for Microsoft.Foo
|
│ Could indicate either that the Resource Provider "Microsoft.Foo" requires
| registration, but this could also indicate that this Azure Region doesn't support | this API version.
|
│ More information on the "skip_provider_registration" flag can be found here:
|
│ https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#skip_provider_registration
│
│ Original Error: Cannnot register providers: Microsoft.DataLakeAnalytics, Microsoft.DBforPostgreSQL, Microsoft.AVS, Microsoft.Media, Microsoft.ApiManagement, Microsoft.Search, Mic
rosoft.Maintenance, Microsoft.ServiceBus, Microsoft.HealthcareApis, Microsoft.Relay, Microsoft.DesktopVirtualization, Microsoft.NotificationHubs, Microsoft.SecurityInsights, Micros
oft.DBforMariaDB, Microsoft.Kusto, Microsoft.DataLakeStore, Microsoft.Automation, Microsoft.CognitiveServices, Microsoft.ManagedServices, Microsoft.EventGrid, Microsoft.BotService,
--- snip ---
At first glance this error look cryptic, but it is quite clear once you understand what Azure resource providers are - I like to think of them as “enabled Azure services” or “enabled Azure features”.
Managing self-hosted GitLab with Terraform
GitLab has an extensive API which allows managing its internal configuration such as users, groups and projects. The official GitLab Terraform provider builds on top of this API.
It assumed here that the Terraform controller (e.g. your laptop) is able to reach your GitLab instance’s TCP port 443 - if it can’t there’s no way Terraform’s API calls will work. The same approach should work with gitlab.com - you can probably (=untested) skip the base_url parameter in that case.
Product launch: 'Puppeteers Cloud Modeling'
Puppeteers has launched a new service product which allows you to gain control of your Cloud resources by having them imported to Terraform. This allows you to manage changes to your Cloud and radically reduces the need for the pesky “who changes this and why?”, “who set this up and is it still needed?” and “what does it do?” discussions. As a bonus you get much better visibility into your cloud.
Terraform stalls when recreating security groups
Sometimes Terraform stalls when trying to remove AWS EC2 security groups and Terraform does no give any hint as to what is wrong. The problem is caused by that security group being attached to an EC2 instance or network interface.
Interestingly Terraform messes up the order of the AWS API calls even when it (attempts to) remove the security group and detach it from all EC2 instances that use it. In other words, Terraform tries to remove the security group before it has been detached from the EC2 instances, which results in the stall:
Terraform resources with dynamic provider values
Sometimes you’d like to pass a dynamic value to a Terraform resource’s provider parameter. This can be done, but some background first.
Terraform allows you to define multiple providers of the same type using provider aliases. This is useful when you’re working with a provider that is tied to a region, the AWS provider being a prime example. The moment you want to create resources in multiple regions you will have to learn provider aliases.
AWS to Azure resource translation table
We use Terraform for managing our Cloud infrastructure. Our customers typically use AWS and that’s what we’re most familiar with. Each public Cloud has its own terminology, so this page is a translation table between Terraform resource names in the AWS and Azure providers:
| AWS | Azure |
|---|---|
| aws_instance | azurerm_linux_virtual_machine |
| aws_network_interface | azurerm_network_interface |
| aws_security_group | azurerm_network_security_group |
| aws_security_group_rule | azurerm_network_security_rule |
| aws_vpc | azurerm_virtual_network |
| aws_subnet | azurerm_subnet |
| inapplicable | azurerm_resource_group |
| aws_s3_bucket | azurerm_storage_account |
| region | location |
Mapping of Terraform AWS resource names to Azure resource names
Sed spell to ease moving to Terraform 0.13
When moving from older versions of Terraform 0.12.x to latest 0.12.x (now: 0.12.29) you may notice the following warnings:
Warning: Interpolation-only expressions are deprecated
on backup.tf line 11, in resource "hcloud_server_network" "backup_example_org":
11: server_id = "${module.backup_example_org.id}"
These make sense, but may come as a surprise as earlier 0.12.x versions were perfectly fine with them.
You may have tons of these, so fixing them manually gets tiresome. The fix is not too difficult, but is quite unreadable due to escaping:
Terraform 0.11->0.12 migration: stabs at the state file
We maintain a rather complex AWS environment built with Terraform that uses nested modules and lots of per-resource provider configurations. Recently the pain of staying with Terraform 0.11 became too much, so we had to start the migration to Terraform 0.12, with 0.13 going to follow soon after. In general the official upgrade instructions were pretty good. Of course there was a lot of manual fixing that had to be done, and as I did not keep detailed notes I can’t recall all the steps I went through. But I think all or most of those can be found from other sources.