<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Ops Community ⚙️: Tony Morris</title>
    <description>The latest articles on The Ops Community ⚙️ by Tony Morris (@tonytalkstech).</description>
    <link>https://community.ops.io/tonytalkstech</link>
    <image>
      <url>https://community.ops.io/images/T-gRTVPpJw4FTRWGcz1ekfr6nmLosmdBKGXCAj36uvg/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS8yMzIvYzU2/YjcyMGItZjdkOC00/NGU4LTljYTUtZDEy/NGNkNzg2NzY4Lmpw/Zw</url>
      <title>The Ops Community ⚙️: Tony Morris</title>
      <link>https://community.ops.io/tonytalkstech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/tonytalkstech"/>
    <language>en</language>
    <item>
      <title>Static Website Playground: Terraform on AWS</title>
      <dc:creator>Tony Morris</dc:creator>
      <pubDate>Tue, 31 May 2022 17:32:17 +0000</pubDate>
      <link>https://community.ops.io/tonytalkstech/static-website-playground-terraform-on-aws-1147</link>
      <guid>https://community.ops.io/tonytalkstech/static-website-playground-terraform-on-aws-1147</guid>
      <description>&lt;p&gt;&lt;a href="https://community.ops.io/images/KZmRj-KkHrMSgnutmxVV1dTXWlQOynSONClu2GbnrLI/w:880/mb:500000/ar:1/aHR0cHM6Ly9pbWFn/ZXMudW5zcGxhc2gu/Y29tL3Bob3RvLTE1/MzkxODY2MDc2MTkt/ZGY0NzZhZmU2ZmYx/P2Nyb3A9ZW50cm9w/eSZjcz10aW55c3Jn/YiZmaXQ9bWF4JmZt/PWpwZyZpeGlkPU1u/d3hNVGMzTTN3d2ZE/RjhjMlZoY21Ob2ZE/RTVmSHh6ZEdGMGFX/TjhaVzU4TUh4OGZI/d3hOak0yTXpNM09U/VTUmaXhsaWI9cmIt/MS4yLjEmcT04MCZ3/PTIwMDA" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/KZmRj-KkHrMSgnutmxVV1dTXWlQOynSONClu2GbnrLI/w:880/mb:500000/ar:1/aHR0cHM6Ly9pbWFn/ZXMudW5zcGxhc2gu/Y29tL3Bob3RvLTE1/MzkxODY2MDc2MTkt/ZGY0NzZhZmU2ZmYx/P2Nyb3A9ZW50cm9w/eSZjcz10aW55c3Jn/YiZmaXQ9bWF4JmZt/PWpwZyZpeGlkPU1u/d3hNVGMzTTN3d2ZE/RjhjMlZoY21Ob2ZE/RTVmSHh6ZEdGMGFX/TjhaVzU4TUh4OGZI/d3hOak0yTXpNM09U/VTUmaXhsaWI9cmIt/MS4yLjEmcT04MCZ3/PTIwMDA" alt="Static Website Playground: Terraform on AWS" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I need a side project, so here I am.&lt;/p&gt;

&lt;p&gt;I make a lot of strong statements about my opinions of public cloud providers and infrastructure-as-code tooling. I figure I may as well back them up with real actual projects.&lt;/p&gt;

&lt;p&gt;This is the first post in a series that I'm calling Static Website Playground. Each post will have the same premise: build a static website and deploy it to a specific public cloud, utilizing some type of infrastructure-as-code tooling.&lt;/p&gt;

&lt;p&gt;This post is about using &lt;strong&gt;Terraform&lt;/strong&gt; to deploy to &lt;strong&gt;AWS&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;The important piece first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL: &lt;a href="https://aws-terraform-static.morriscloud.com/"&gt;https://aws-terraform-static.morriscloud.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was going to draw a diagram to represent the architectural layout here, but... it's super simple. So I'll just discuss the interest bits below.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub
&lt;/h1&gt;

&lt;p&gt;URL: &lt;a href="https://github.com/morriscloud/static-website-playground/tree/main/terraform/aws"&gt;https://github.com/morriscloud/static-website-playground/tree/main/terraform/aws&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each of these static websites is stored in the same repository and organized by IaC provider and then by cloud provider.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cloudflare
&lt;/h1&gt;

&lt;p&gt;Every post in this series will be using Cloudflare as the public DNS provider. I've got a Zone that I created previously (&lt;code&gt;morriscloud.com&lt;/code&gt;), so this part is super simple. I look up the Zone using a &lt;code&gt;data&lt;/code&gt; resource, then I create a new CNAME Record in the Zone that points to the S3 bucket's website endpoint. More on that part later.&lt;/p&gt;

&lt;p&gt;Note that I recently had to update this to use the new S3 resources in the Terraform AWS provider, so I'm now using &lt;code&gt;aws_s3_bucket_website_configuration.this.website_endpoint&lt;/code&gt; as the CNAME target, rather than the previous &lt;code&gt;aws_s3_bucket.this.website_endpoint&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  AWS
&lt;/h1&gt;

&lt;p&gt;This deployment is as bare-bones as possible in AWS. It creates an S3 bucket, uploads an HTML file &lt;code&gt;index.html&lt;/code&gt;, and sets some properties on the bucket to enable it to be viewed as a public website. There's a small bucket policy that's also attached to the bucket, allowing &lt;code&gt;GetObject&lt;/code&gt; access to the objects in the specified bucket from anywhere in the world.&lt;/p&gt;

&lt;h1&gt;
  
  
  Terraform Cloud
&lt;/h1&gt;

&lt;p&gt;To deploy the resources, I use the free version of Terraform Cloud. I connect a workspace to my GitHub repository, then I use the working directory to point to the correct subdirectory in the repository.&lt;/p&gt;

&lt;p&gt;Using this project as an example, I have a workspace named &lt;code&gt;static-website-playground-aws-terraform&lt;/code&gt;, pointed to the GitHub repository linked above, and then set to &lt;code&gt;terraform/aws&lt;/code&gt; as its working directory.&lt;/p&gt;

&lt;p&gt;Using Terraform Cloud gives me a nice hook directly into Pull Requests (if you enable it), plus I can see the changes that I'm making in a feature branch easily.&lt;/p&gt;

&lt;p&gt;It's important to note that my favorite feature of using Terraform Cloud is the ability to run &lt;code&gt;terraform plan&lt;/code&gt; from my local console pointed to the remote workspace. This runs the plan in a Terraform Cloud runner with all the variables defined there, rather than somewhere on my laptop that I could accidentally commit to source.&lt;/p&gt;




&lt;h1&gt;
  
  
  What's Next?
&lt;/h1&gt;

&lt;p&gt;Next up will be using Pulumi to deploy to AWS. Obviously it won't have Terraform Cloud, but I imagine most of the rest of it will be exactly the same. Stay tuned!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>terraform</category>
    </item>
    <item>
      <title>Don't Manage Terraform Enterprise With Terraform</title>
      <dc:creator>Tony Morris</dc:creator>
      <pubDate>Thu, 26 May 2022 15:13:07 +0000</pubDate>
      <link>https://community.ops.io/tonytalkstech/dont-manage-terraform-enterprise-with-terraform-261k</link>
      <guid>https://community.ops.io/tonytalkstech/dont-manage-terraform-enterprise-with-terraform-261k</guid>
      <description>&lt;p&gt;&lt;em&gt;Don't do it. I know you want to, and you should not.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Ov7MwRXwniT9XbXfG_LFfdUseNP0osUmb6hUdzHhg_Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9pbWFn/ZXMudW5zcGxhc2gu/Y29tL3Bob3RvLTE1/NDY2MTc4ODUtNDgy/MjEyNWY4OTFlP2Ny/b3A9ZW50cm9weSZj/cz10aW55c3JnYiZm/aXQ9bWF4JmZtPWpw/ZyZpeGlkPU1ud3hN/VGMzTTN3d2ZERjhj/MlZoY21Ob2ZEUjhm/SE4wYjNCOFpXNThN/SHg4Zkh3eE5qSTRN/amM0TXpjeSZpeGxp/Yj1yYi0xLjIuMSZx/PTgwJnc9MjAwMA" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Ov7MwRXwniT9XbXfG_LFfdUseNP0osUmb6hUdzHhg_Y/w:880/mb:500000/ar:1/aHR0cHM6Ly9pbWFn/ZXMudW5zcGxhc2gu/Y29tL3Bob3RvLTE1/NDY2MTc4ODUtNDgy/MjEyNWY4OTFlP2Ny/b3A9ZW50cm9weSZj/cz10aW55c3JnYiZm/aXQ9bWF4JmZtPWpw/ZyZpeGlkPU1ud3hN/VGMzTTN3d2ZERjhj/MlZoY21Ob2ZEUjhm/SE4wYjNCOFpXNThN/SHg4Zkh3eE5qSTRN/amM0TXpjeSZpeGxp/Yj1yYi0xLjIuMSZx/PTgwJnc9MjAwMA" alt="Don't Manage Terraform Enterprise With Terraform" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, some facts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.terraform.io/docs/enterprise/index.html"&gt;Terraform Enterprise&lt;/a&gt; is a wonderful product. It's the self-hosted distribution of Terraform Cloud for organizations that want the privacy and scale of an enterprise-grade installation.&lt;/li&gt;
&lt;li&gt;There exists a &lt;a href="https://registry.terraform.io/providers/hashicorp/tfe/latest/docs"&gt;Terraform Cloud/Enterprise Provider&lt;/a&gt; that can easily template and manage how an organization creates Workspaces (and other TFC/TFE resources).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given the generally painful user experience of entering dozens of Workspace Variables into the TFE, it makes sense that nearly everyone I've worked with has stated a desire to use the &lt;code&gt;tfe&lt;/code&gt; provider to manage workspaces. I'm here to tell you why this ends up being a rougher idea than you hoped for.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pricing
&lt;/h1&gt;

&lt;p&gt;Terraform Enterprise is priced by the number of Workspaces you have.&lt;br&gt;&lt;br&gt;
They're not cheap.&lt;/p&gt;

&lt;p&gt;If you start dedicated Workspaces to creating and managing other Workspaces, you're effectively shorting yourself out of your own licenses.&lt;/p&gt;

&lt;p&gt;On the other hand, if you're in Terraform Cloud, you're not paying per-Workspace, so feel free to use this method if the following hiccups don't pertain to you.&lt;/p&gt;

&lt;p&gt;For what it's worth, if HashiCorp had a concept of "Configuration Workspaces" that didn't hit against your Workspace count, then this would obviously not be an issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  Multi-Step Updates
&lt;/h1&gt;

&lt;p&gt;Let's say you can get over the pricing issue. Talking through how the Configuration Workspaces would be architected and deployed brings up some other potential issues.&lt;/p&gt;

&lt;p&gt;First, a quick overview of how we had tried this out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/Fg2D3YtGjPWbAYgGVx1PDfezlHjhuHLkVqiLWGQLCM8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzQzNzdx/NmNpa3RuODdjdG5n/bjZyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/Fg2D3YtGjPWbAYgGVx1PDfezlHjhuHLkVqiLWGQLCM8/w:880/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL2Fy/dGljbGVzLzQzNzdx/NmNpa3RuODdjdG5n/bjZyLnBuZw" alt="TFE Management with Terraform" width="880" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Workspace Repository
&lt;/h3&gt;

&lt;p&gt;The most important piece of functionality here is the Terraform module that uses the &lt;code&gt;tfe&lt;/code&gt; provider to create the Workload Workspaces.&lt;/p&gt;

&lt;p&gt;Everything about the Workload Workspace is contained within this Workspace Repository, including the Workspace Variables.&lt;/p&gt;

&lt;p&gt;Another name for this repository could be a "Configuration Repository," as it &lt;em&gt;configures&lt;/em&gt; the implementation of the Workload Repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workload Repository
&lt;/h3&gt;

&lt;p&gt;The Workload Repository defines the Terraform resources to create the workloads that you are configuring. For us, this is a bunch of resources from the &lt;code&gt;aws&lt;/code&gt; provider, but it could be anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Workspace
&lt;/h3&gt;

&lt;p&gt;The Configuration Workspace in Terraform Enterprise is pointed to the Workspace Repository. When it executes a Run, it generates Terraform Enterprise resources, such as the Workload Workspaces and the requisite Workspace Variables in each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workload Workspace
&lt;/h3&gt;

&lt;p&gt;The Workload Workspace is created by the Configuration Workspace and pointed to the Workload Repository. When it executes a Run, it generates Workload-specific resources. In our cases, this is generally AWS resources such as EC2 instances, EBS volumes, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The biggest problem with this setup is the back-and-forth you have to do in order to make changes.&lt;/p&gt;

&lt;p&gt;Let's say you want to add a resource to the Workload Repository. This is straightforward, and it doesn't cause many issues. You would just commit your changes to the Workload Repository, and the Workload Workspace would pick those up.&lt;/p&gt;

&lt;p&gt;What if, however, that introduces a new variable to the repository? The changes you would have to make in order to get it through the system look something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the Workspace Variable resource to the Workspace Repository.&lt;/li&gt;
&lt;li&gt;Push the Run through the Configuration Workspace to add the TFE Workspace Variable to the Workload Workspace.&lt;/li&gt;
&lt;li&gt;Add the variable to the Workload Repository.&lt;/li&gt;
&lt;li&gt;You can finally push the Run through the Workload Workspace.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Four steps for a simple variable addition seems like a tough solution to roll out to any team.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Should You Do Instead?
&lt;/h1&gt;

&lt;p&gt;Let's be honest. I'm certain there are some really creative ways to work around these limitations managing Terraform at-scale. Feel free to use them and tell me what they are! &lt;a href="https://twitter.com/tonytalkstech"&gt;Hit me up on Twitter&lt;/a&gt; if you find a really neat solution!&lt;/p&gt;

&lt;p&gt;For our use cases, we are building out a Control Plane that abstracts that business-level functions from TFE itself. So, instead of thinking about "I need to create this TFE Workspaces with these Workspace Variables," we are now thinking "This team needs to create this application cluster."&lt;/p&gt;

&lt;p&gt;This abstraction is not unique. I've talked to many people in the community that do a similar thing.&lt;/p&gt;

&lt;p&gt;This solution works really well for us because we have a number of backend systems that we need to integrate together during an "application cluster spin-up." These include SaaS tools, such as PagerDuty, Splunk, New Relic, and many others. Given that Terraform Enterprise has a robust API, it makes our Control Plane much more straightforward to implement.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
