<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Terraform on Puppeteers Oy</title>
		<link>https://www.puppeteers.net/tags/terraform/</link>
		<description>Recent content in Terraform on Puppeteers Oy</description>
		<generator>Hugo</generator>
		<language>en-US</language>
		
		
		
		
			<lastBuildDate>Wed, 11 Jan 2023 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://www.puppeteers.net/tags/terraform/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Debugging Terraform AWS UnauthorizedOperation errors</title>
				<link>https://www.puppeteers.net/blog/debugging-terraform-aws-unauthorizedoperation-errors/</link>
				<pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/debugging-terraform-aws-unauthorizedoperation-errors/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/pexels-jake-young-732894.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;causes-for-the-terraform-aws-unauthorizedoperation-errors&#34;&gt;Causes for the Terraform AWS UnauthorizedOperation errors&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.puppeteers.net/learn/what-is-terraform-and-how-does-it-work/&#34;&gt;Terraform&lt;/a&gt; is an &lt;a href=&#34;https://www.puppeteers.net/learn/understanding-infrastructure-as-code-iac/&#34;&gt;infrastructure as code&lt;/a&gt; tool you can use to configure Cloud resources in AWS. When using &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs&#34;&gt;Terraform AWS provider&lt;/a&gt; you frequently run into various UnauthorizedOperation errors when creating, modifying or deleting resources. That happens unless you do what you should &lt;em&gt;not&lt;/em&gt; do and let Terraform use an AWS API key tied to an IAM user with full admin privileges. In almost all cases Terraform UnauthorizedOperation errors are caused by missing IAM permissions. It can sometimes be a bit tedious to get to the root cause, because Terraform may not show it in its normal output.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform downloads the deprecated azure provider</title>
				<link>https://www.puppeteers.net/blog/terraform-downloads-the-deprecated-azure-provider/</link>
				<pubDate>Tue, 20 Dec 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-downloads-the-deprecated-azure-provider/</guid>
				<description>&lt;p&gt;You are 100% sure that all your Terraform resources are using &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs&#34;&gt;terraform-provider-azurerm&lt;/a&gt;, yet Terraform attempts to download the deprecated &amp;ldquo;azure&amp;rdquo; provider:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ terraform init&#xA;Initializing modules...&#xA;&#xA;Initializing the backend...&#xA;&#xA;Initializing provider plugins...&#xA;- Finding hashicorp/local versions matching &amp;#34;2.2.3&amp;#34;...&#xA;- Finding latest version of hashicorp/azure...&#xA;- Finding hashicorp/azurerm versions matching &amp;#34;3.17.0&amp;#34;...&#xA;- Installing hashicorp/local v2.2.3...&#xA;- Installed hashicorp/local v2.2.3 (signed by HashiCorp)&#xA;- Installing hashicorp/azurerm v3.17.0...&#xA;- Installed hashicorp/azurerm v3.17.0 (signed by HashiCorp)&#xA;╷&#xA;│ Error: Failed to query available provider packages&#xA;│ &#xA;│ Could not retrieve the list of available versions for provider hashicorp/azure: provider registry registry.terraform.io does not have a provider named&#xA;│ registry.terraform.io/hashicorp/azure&#xA;│ &#xA;│ Did you intend to use terraform-providers/azure? If so, you must specify that source address in each module which requires that provider. To see which&#xA;│ modules are currently depending on hashicorp/azure, run the following command:&#xA;│     terraform providers&#xA;╵&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;You grep the state file and find no references to the &amp;ldquo;azure&amp;rdquo; provider. You assume that the cause is some nested module that depends on it, but no, that&amp;rsquo;s not it. You run &amp;ldquo;terraform providers&amp;rdquo; and see that indeed, the &amp;ldquo;azure&amp;rdquo; provider is required:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Importing DNS records from Cloudflare to Terraform</title>
				<link>https://www.puppeteers.net/blog/importing-dns-records-from-cloudflare-to-terraform/</link>
				<pubDate>Fri, 30 Sep 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/importing-dns-records-from-cloudflare-to-terraform/</guid>
				<description>&lt;p&gt;&lt;img src=&#34;https://puppeteers-public.hel1.your-objectstorage.com/bpmn-cloudflare-dns2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Computers were supposed to relieve us humans from boring and repetitive jobs. Here we turn this upside down and do the boring and repetitive job of a computer by importing Cloudflare DNS records to Terraform ourselves. Not fun, but someone’s gotta do it sometimes. If you’re reading this, that someone is probably you. Condolences. My hope is that someone lazy enough gets bored enough to write a program to do this. I didn’t. Yet. &lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform, AWS Cloudfront and CNAMEAlreadyExists error</title>
				<link>https://www.puppeteers.net/blog/terraform-aws-cloudfront-and-cnamealreadyexists-error/</link>
				<pubDate>Sat, 17 Sep 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-aws-cloudfront-and-cnamealreadyexists-error/</guid>
				<description>&lt;p&gt;When you create a distribution, AWS creates several DNS A records with the same name (e.g. &lt;em&gt;d25gma2ea3ckma.cloudfront.net&lt;/em&gt;) which point to IPs the distribution is using. Then, typically, you would define CNAME(s) pointing to that cloudfront.net address in your own DNS. Each Cloudfront distribution has a list of aliases, similar to Subject Alternative Names (&amp;ldquo;SAN&amp;rdquo;) in SSL certificates. The aliases should match the CNAME(s) you&amp;rsquo;ve set in DNS.&lt;/p&gt;&#xA;&lt;p&gt;Now, this is all good until you need to migrate those Cloudfront distributions to, say, a new AWS account. If you attempt to create a new distribution (here with Terraform) with the same alias you will get this error:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Enabling Azure Backup on Linux VMs with Terraform</title>
				<link>https://www.puppeteers.net/blog/enabling-azure-backup-on-linux-vms-with-terraform/</link>
				<pubDate>Mon, 05 Sep 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/enabling-azure-backup-on-linux-vms-with-terraform/</guid>
				<description>&lt;p&gt;This article shows you how to enable Azure Backup on Linux VMs. It is recommended to read the &lt;a href=&#34;https://www.puppeteers.net/blog/understanding-azure-backup-for-linux-vms/&#34;&gt;Understanding Azure Backup for Linux VMs&lt;/a&gt; article first before trying to enable backups with Terraform. Terraform AzureRM provider has three relevant resources:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine&#34;&gt;azurerm_linux_virtual_machine&lt;/a&gt;: parameters &lt;em&gt;provision_vm_agent&lt;/em&gt; and &lt;em&gt;allow_extension_operations&lt;/em&gt; should be &lt;em&gt;true&lt;/em&gt; or enabling backups will fail (with or without Terraform)&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension&#34;&gt;azurerm_virtual_machine_extension&lt;/a&gt;: this can be used to run/enable a VM extension on a VM&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_protected_vm&#34;&gt;azurerm_backup_protected_vm&lt;/a&gt;: this resource enables backups on a VM&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault&#34;&gt;azurerm_recovery_services_vault&lt;/a&gt;: the recovery services vault where backups will be stored&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_policy_vm&#34;&gt;azurerm_backup_policy_vm&lt;/a&gt;: backup schedule and retainment rules&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll go through the basic process first, which may work for some people. I&amp;rsquo;ll then take a deep dive into the timeout issues you &lt;em&gt;may&lt;/em&gt; or &lt;em&gt;may not&lt;/em&gt; encounter in your environment.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform: converting an  aws_instance network interface into an explicitly managed interface</title>
				<link>https://www.puppeteers.net/blog/terraform-converting-an-aws_instance-network-interface-into-an-explicitly-managed-interface/</link>
				<pubDate>Tue, 23 Aug 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-converting-an-aws_instance-network-interface-into-an-explicitly-managed-interface/</guid>
				<description>&lt;p&gt;The &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance&#34;&gt;aws_instance resource&lt;/a&gt; in Terraform can automatically create the default network interface for you. There are cases, however, when you notice that the default network interface is not enough anymore, and modifying it via the limited aws_instance parameters is not sufficient. In these cases you &lt;em&gt;can&lt;/em&gt; convert the interface into an &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_interface&#34;&gt;aws_network_interface resource&lt;/a&gt;, but the process is far from straightforward.&lt;/p&gt;&#xA;&lt;p&gt;The first step is to create a Terraform resource for the network interface:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform, Azure and MissingSubscriptionRegistration</title>
				<link>https://www.puppeteers.net/blog/terraform-azure-and-missingsubscriptionregistration/</link>
				<pubDate>Sat, 20 Aug 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-azure-and-missingsubscriptionregistration/</guid>
				<description>&lt;p&gt;When deploying with Terraform to Azure you may sometimes encounter errors such as this:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;╷                                                                                                                                                             &#xA;│ Error: creating Automation Account (Subscription: &amp;#34;83fa140a-2bea-175a-395c-914cae2902ce&amp;#34;                                                                    &#xA;│ Resource Group Name: &amp;#34;production&amp;#34;                                             &#xA;│ Automation Account Name: &amp;#34;backup-automation&amp;#34;): automationaccount.AutomationAccountClient#CreateOrUpdate: Failure responding to request: StatusCode=409 -- Or&#xA;iginal Error: autorest/azure: Service returned an error. Status=409 Code=&amp;#34;MissingSubscriptionRegistration&amp;#34; Message=&amp;#34;The subscription is not registered to use &#xA;namespace &amp;#39;Microsoft.Automation&amp;#39;. See https://aka.ms/rps-not-found for how to register subscriptions.&amp;#34; Details=[{&amp;#34;code&amp;#34;:&amp;#34;MissingSubscriptionRegistration&amp;#34;,&amp;#34;mes&#xA;sage&amp;#34;:&amp;#34;The subscription is not registered to use namespace &amp;#39;Microsoft.Automation&amp;#39;. See https://aka.ms/rps-not-found for how to register subscriptions.&amp;#34;,&amp;#34;targe&#xA;t&amp;#34;:&amp;#34;Microsoft.Automation&amp;#34;}]&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;The problem is that in Azure you may need to register the &lt;em&gt;provider&lt;/em&gt; for the service you intend to manage with Terraform. If you add resources from Azure Portal this registration part is handled automation. In the above case the Azure Automation provider was missing.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Modern cronjob part 1: Azure Automation with Terraform</title>
				<link>https://www.puppeteers.net/blog/modern-cronjob-part-1-azure-automation-with-terraform/</link>
				<pubDate>Thu, 11 Aug 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/modern-cronjob-part-1-azure-automation-with-terraform/</guid>
				<description>&lt;p&gt;Microsoft Azure has a nice service for scheduling tasks called &lt;a href=&#34;https://duckduckgo.com/?q=azure&amp;#43;automation&amp;amp;t=newext&amp;amp;atb=v310-1&amp;amp;ia=web&#34;&gt;Azure Automation&lt;/a&gt;. While Azure Automation is able to other things as well, such as being able to act as a Powershell DSC pull server, we&amp;rsquo;ll focus on the runbooks and scheduling. Runbooks are scripts that do things, e.g. run maintenance and reporting tasks. Runbooks often, but not necessarily manipulate objects in Azure. Runbooks are serverless like Azure Functions and the pricing is therefore similar - you pay for the amount of computing resources you use and don&amp;rsquo;t have to pay for a server that&amp;rsquo;s mostly idle.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Multi-part cloud-init provisioning with Terraform</title>
				<link>https://www.puppeteers.net/blog/multi-part-cloud-init-provisioning-with-terraform/</link>
				<pubDate>Thu, 28 Apr 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/multi-part-cloud-init-provisioning-with-terraform/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://cloud-init.io/&#34;&gt;Cloud-Init&lt;/a&gt; is &amp;ldquo;a standard for customizing&amp;rdquo; cloud instances, typically on their first boot. It is allows mixing state-based configuration management with imperative provisioning commands (details in &lt;a href=&#34;https://www.puppeteers.net/learn/understanding-infrastructure-as-code-iac/&#34;&gt;our IaC article&lt;/a&gt;). By using cloud-init most of the annoyances of SSH-based provisioning can be avoided:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Having to use (possibly shared) SSH keys for provisioning&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Having to have direct network access to the VM being provisioned (may require a VPN connection)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;That said, neither cloud-init itself, nor its use within Terraform is particularly well documented. Therefore it can be an effort to create cloud-init-based provisioning that works &lt;em&gt;and&lt;/em&gt; adapts easily to different use-cases. This article attempts to fill that gap to some extent.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Data-driven Terraform: Kubernetes cluster in Hetzner Cloud</title>
				<link>https://www.puppeteers.net/blog/data-driven-terraform-kubernetes-cluster-in-hetzner-cloud/</link>
				<pubDate>Fri, 15 Apr 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/data-driven-terraform-kubernetes-cluster-in-hetzner-cloud/</guid>
				<description>&lt;p&gt;Terraform does not have a particularly strong decoupling between &lt;em&gt;data&lt;/em&gt; and &lt;em&gt;code&lt;/em&gt;, at least not from a best practices perspective. It is possible and useful, however, to use data to define Terraform resources - if not for any other reason but to reduce code repetition for common resources that require defining lots of parameters. Here&amp;rsquo;s an example of setting up a Kubernetes cluster in Hetzner Cloud using Terraform with a &amp;ldquo;data-driven&amp;rdquo; approach:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform Enum data type</title>
				<link>https://www.puppeteers.net/blog/terraform-enum-data-type/</link>
				<pubDate>Tue, 12 Apr 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-enum-data-type/</guid>
				<description>&lt;p&gt;In Terraform you have access to basic data types like &lt;em&gt;bool&lt;/em&gt; or &lt;em&gt;string&lt;/em&gt;. 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.&lt;/p&gt;&#xA;&lt;p&gt;Terraform, &lt;a href=&#34;https://puppet.com/docs/puppet/7/lang_data_abstract.html#enum-data-type&#34;&gt;unlike Puppet&lt;/a&gt;, does not have a built-in Enum data type. However, you can emulate an Enum like this:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Conditional provisioner blocks in Terraform</title>
				<link>https://www.puppeteers.net/blog/conditional-provisioner-blocks-in-terraform/</link>
				<pubDate>Wed, 05 Jan 2022 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/conditional-provisioner-blocks-in-terraform/</guid>
				<description>&lt;p&gt;I&amp;rsquo;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 &lt;a href=&#34;https://www.puppeteers.net/blog/multi-part-cloud-init-provisioning-with-terraform/&#34;&gt;Multi-part cloud-init provisioning with Terraform&lt;/a&gt; blog post.&lt;/p&gt;&#xA;&lt;p&gt;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.&lt;/p&gt;&#xA;&lt;p&gt;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 &lt;em&gt;aws_instance&lt;/em&gt;. Those resources are identical except for the provisioner blocks:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform Azure resource provider registration fails</title>
				<link>https://www.puppeteers.net/blog/terraform-azure-resource-provider-registration-fails/</link>
				<pubDate>Tue, 26 Oct 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-azure-resource-provider-registration-fails/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://www.terraform.io/&#34;&gt;Terraform&lt;/a&gt; has good support for &lt;a href=&#34;https://azure.microsoft.com/en-us/&#34;&gt;Microsoft Azure&lt;/a&gt; through the &lt;a href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs&#34;&gt;Terraform Azure provider&lt;/a&gt; and the &lt;a href=&#34;https://www.terraform.io/docs/language/settings/backends/azurerm.html&#34;&gt;AzureRM backend&lt;/a&gt;. However, you may hit a glitch when adding or importing resources if you lack permissions to register Azure resource providers:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;│ Error: Error ensuring Resource Providers are registered.&#xA;|&#xA;│ Terraform automatically attempts to register the Resource Providers it supports&#xA;| to ensure it&amp;#39;s able to provision resources.&#xA;│                                                                                                                                                                                   &#xA;│ If you don&amp;#39;t have permission to register Resource Providers you may wish to use&#xA;| the &amp;#34;skip_provider_registration&amp;#34; flag in the Provider block to disable this&#xA;| functionality.&#xA;│                                                                                                                                                                                   &#xA;│ Please note that if you opt out of Resource Provider Registration and Terraform&#xA;| tries to provision a resource from a Resource Provider which is unregistered,&#xA;| then the error may appear misleading - for example&#xA;|                                                                                                                                                                                   &#xA;│ &amp;gt; API version 2019-XX-XX was not found for Microsoft.Foo&#xA;|                                                                                                                                                                                   &#xA;│ Could indicate either that the Resource Provider &amp;#34;Microsoft.Foo&amp;#34; requires&#xA;| registration, but this could also indicate that this Azure Region doesn&amp;#39;t support | this API version.&#xA;|&#xA;│ More information on the &amp;#34;skip_provider_registration&amp;#34; flag can be found here:&#xA;|&#xA;│ https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#skip_provider_registration&#xA;│&#xA;│ Original Error: Cannnot register providers: Microsoft.DataLakeAnalytics, Microsoft.DBforPostgreSQL, Microsoft.AVS, Microsoft.Media, Microsoft.ApiManagement, Microsoft.Search, Mic&#xA;rosoft.Maintenance, Microsoft.ServiceBus, Microsoft.HealthcareApis, Microsoft.Relay, Microsoft.DesktopVirtualization, Microsoft.NotificationHubs, Microsoft.SecurityInsights, Micros&#xA;oft.DBforMariaDB, Microsoft.Kusto, Microsoft.DataLakeStore, Microsoft.Automation, Microsoft.CognitiveServices, Microsoft.ManagedServices, Microsoft.EventGrid, Microsoft.BotService,&#xA;&#xA;--- snip ---&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;At first glance this error look cryptic, but it is quite clear once you understand &lt;a href=&#34;https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types&#34;&gt;what Azure resource providers are&lt;/a&gt; - I like to think of them as &lt;em&gt;&amp;ldquo;enabled Azure services&amp;rdquo;&lt;/em&gt; or &lt;em&gt;&amp;ldquo;enabled Azure features&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Managing self-hosted GitLab with Terraform</title>
				<link>https://www.puppeteers.net/blog/managing-self-hosted-gitlab-with-terraform/</link>
				<pubDate>Sun, 16 May 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/managing-self-hosted-gitlab-with-terraform/</guid>
				<description>&lt;p&gt;GitLab has an &lt;a href=&#34;https://docs.gitlab.com/ee/api/&#34;&gt;extensive API&lt;/a&gt; which allows managing its internal configuration such as users, groups and projects. The official &lt;a href=&#34;https://registry.terraform.io/providers/gitlabhq/gitlab/latest&#34;&gt;GitLab Terraform provider&lt;/a&gt; builds on top of this API.&lt;/p&gt;&#xA;&lt;p&gt;It assumed here that the Terraform controller (e.g. your laptop) is able to reach your GitLab instance&amp;rsquo;s TCP port 443 - if it can&amp;rsquo;t there&amp;rsquo;s no way Terraform&amp;rsquo;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.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Product launch: &#39;Puppeteers Cloud Modeling&#39;</title>
				<link>https://www.puppeteers.net/blog/product-launch-puppeteers-cloud-modeling/</link>
				<pubDate>Tue, 13 Apr 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/product-launch-puppeteers-cloud-modeling/</guid>
				<description>&lt;p&gt;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 &amp;ldquo;who changes this and why?&amp;rdquo;, &amp;ldquo;who set this up and is it still needed?&amp;rdquo; and &amp;ldquo;what does it do?&amp;rdquo; discussions. As a bonus you get much better visibility into your cloud.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform stalls when recreating security groups</title>
				<link>https://www.puppeteers.net/blog/terraform-stalls-when-recreating-security-groups/</link>
				<pubDate>Tue, 23 Mar 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-stalls-when-recreating-security-groups/</guid>
				<description>&lt;p&gt;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.&lt;/p&gt;&#xA;&lt;p&gt;Interestingly Terraform messes up the order of the AWS API calls even when it (attempts to) remove the security group &lt;em&gt;and&lt;/em&gt; 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:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform resources with dynamic provider values</title>
				<link>https://www.puppeteers.net/blog/terraform-resources-with-dynamic-provider-values/</link>
				<pubDate>Thu, 11 Feb 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-resources-with-dynamic-provider-values/</guid>
				<description>&lt;p&gt;Sometimes you&amp;rsquo;d like to pass a dynamic value to a Terraform resource&amp;rsquo;s provider parameter. This can be done, but some background first.&lt;/p&gt;&#xA;&lt;p&gt;Terraform allows you to &lt;a href=&#34;https://www.terraform.io/docs/language/meta-arguments/resource-provider.html&#34;&gt;define multiple providers of the same type&lt;/a&gt; using provider &lt;em&gt;aliases&lt;/em&gt;. This is useful when you&amp;rsquo;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.&lt;/p&gt;</description>
			</item>
			<item>
				<title>AWS to Azure resource translation table</title>
				<link>https://www.puppeteers.net/blog/aws-to-azure-resource-translation-table/</link>
				<pubDate>Sun, 17 Jan 2021 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/aws-to-azure-resource-translation-table/</guid>
				<description>&lt;p&gt;We use Terraform for managing our Cloud infrastructure. Our customers typically use AWS and that&amp;rsquo;s what we&amp;rsquo;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:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;&lt;strong&gt;Azure&lt;/strong&gt;&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_instance&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_linux_virtual_machine&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_network_interface&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_network_interface&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_security_group&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_network_security_group&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_security_group_rule&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_network_security_rule&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_vpc&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_virtual_network&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_subnet&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_subnet&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;inapplicable&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_resource_group&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;aws_s3_bucket&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;azurerm_storage_account&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;region&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;location&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Mapping of Terraform AWS resource names to Azure resource names&lt;/p&gt;</description>
			</item>
			<item>
				<title>Sed spell to ease moving to Terraform 0.13</title>
				<link>https://www.puppeteers.net/blog/sed-spell-to-ease-moving-to-terraform-0-13/</link>
				<pubDate>Mon, 28 Dec 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/sed-spell-to-ease-moving-to-terraform-0-13/</guid>
				<description>&lt;p&gt;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:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Warning: Interpolation-only expressions are deprecated                                                                                                                              &#xA;&#xA;  on backup.tf line 11, in resource &amp;#34;hcloud_server_network&amp;#34; &amp;#34;backup_example_org&amp;#34;:                                                                                                 &#xA;  11:   server_id = &amp;#34;${module.backup_example_org.id}&amp;#34;        &lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;These make sense, but may come as a surprise as earlier 0.12.x versions were perfectly fine with them.&lt;/p&gt;&#xA;&lt;p&gt;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:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform 0.11-&gt;0.12 migration: stabs at the state file</title>
				<link>https://www.puppeteers.net/blog/terraform-0-11-0-12-migration-stabs-at-the-state-file/</link>
				<pubDate>Fri, 30 Oct 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-0-11-0-12-migration-stabs-at-the-state-file/</guid>
				<description>&lt;p&gt;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 &lt;a href=&#34;https://www.terraform.io/upgrade-guides/0-12.html&#34;&gt;official upgrade instructions&lt;/a&gt; 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&amp;rsquo;t recall all the steps I went through. But I think all or most of those can be found from other sources.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform: Importing resources from a non-default AWS region</title>
				<link>https://www.puppeteers.net/blog/terraform-importing-resources-from-a-non-default-aws-region/</link>
				<pubDate>Tue, 04 Feb 2020 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-importing-resources-from-a-non-default-aws-region/</guid>
				<description>&lt;p&gt;I recently - again - had to import resources to Terraform (0.11.14) from AWS that were outside of the default AWS region and were managed in a nested (non-root) module. The root module contained the provider configuration, including multiple aliases to allow creation of resources in different regions, as well as the nested module call, here in a very simple version:&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;provider &amp;#34;aws&amp;#34; {&#xA;  region = &amp;#34;us-west-2&amp;#34;&#xA;}&#xA;&#xA;provider &amp;#34;aws&amp;#34; {&#xA;  region = &amp;#34;us-east-1&amp;#34;&#xA;  alias  = &amp;#34;us-east-1&amp;#34;&#xA;}&#xA;&#xA;provider &amp;#34;aws&amp;#34; {&#xA;  region = &amp;#34;us-west-2&amp;#34;&#xA;  alias  = &amp;#34;us-west-2&amp;#34;&#xA;}&#xA;&#xA;module &amp;#34;cloud&amp;#34; {&#xA;  param = value&#xA;}&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;The goal was to import some &lt;a href=&#34;https://www.terraform.io/docs/providers/aws/r/ses_email_identity.html&#34;&gt;aws_ses_email_identity&lt;/a&gt; resources into the &amp;ldquo;cloud&amp;rdquo; module. So, originally the cloud module had this:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Terraform S3 access denied problems</title>
				<link>https://www.puppeteers.net/blog/terraform-s3-access-denied-problems/</link>
				<pubDate>Wed, 11 Sep 2019 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/terraform-s3-access-denied-problems/</guid>
				<description>&lt;p&gt;I&amp;rsquo;ve stumbled upon interesting access denied problems with S3-based Terraform state files recently. Suppose you have two or more Terraform root modules which use the same bucket for storing the state and just use a different key (=state file):&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;terraform {   backend &amp;#34;s3&amp;#34; {     bucket = &amp;#34;terraform-state&amp;#34;     key    = &amp;#34;root-module-1&amp;#34;     region = &amp;#34;eu-central-1&amp;#34;   } }&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;and&lt;/p&gt;&#xA;&lt;div class=&#34;code-block&#34;&gt;&#xA;    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;&#xA;      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;&#xA;    &lt;/button&gt;&#xA;    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;terraform {   backend &amp;#34;s3&amp;#34; {     bucket = &amp;#34;terraform-state&amp;#34;     key    = &amp;#34;root-module-2&amp;#34;     region = &amp;#34;eu-central-1&amp;#34;   } }&lt;/code&gt;&lt;/pre&gt;&#xA;  &lt;/div&gt;&lt;p&gt;However, trying to access the state file in one root module works, but on the other you get a generic S3 Access Denied error:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Lack of default connection settings in Terraform 0.12.x</title>
				<link>https://www.puppeteers.net/blog/lack-of-default-connection-settings-in-terraform-0-12-x/</link>
				<pubDate>Thu, 29 Aug 2019 00:00:00 +0000</pubDate>
				<guid>https://www.puppeteers.net/blog/lack-of-default-connection-settings-in-terraform-0-12-x/</guid>
				<description>&lt;p&gt;I was recently bit by a feature (one might call it a bug) in Terraform. We wanted to try out the &amp;ldquo;Networks&amp;rdquo; feature in &lt;a href=&#34;https://www.hetzner.com/cloud&#34;&gt;Hetzner Cloud&lt;/a&gt; but that required upgrading &lt;a href=&#34;https://github.com/terraform-providers/terraform-provider-hcloud&#34;&gt;terraform-provider-hcloud&lt;/a&gt;, which in turn required upgrading Terraform to 0.12.x. For the most part migration from 0.11.x code to 0.12.x code was straightforward with some help from the automated migration tool. I even went as far as read some of the migration documentation, but missed one important part: &lt;a href=&#34;https://www.terraform.io/upgrade-guides/0-12.html#default-settings-in-connection-blocks&#34;&gt;connection blocks no longer have default values.&lt;/a&gt; To make the matter worse Terraform 0.12 does not error out if values are unset: instead if just runs the provisioner and then times out. This seems to be related to &lt;a href=&#34;https://github.com/hashicorp/terraform/issues/21690&#34;&gt;Terraform bug #21690&lt;/a&gt;.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
