<?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>Forem: Josh Pollara</title>
    <description>The latest articles on Forem by Josh Pollara (@joshpollara).</description>
    <link>https://forem.com/joshpollara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F666291%2F0c166eb4-a937-45b6-8a8f-9406396dc002.jpeg</url>
      <title>Forem: Josh Pollara</title>
      <link>https://forem.com/joshpollara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joshpollara"/>
    <language>en</language>
    <item>
      <title>Building in Public: Pricing is our scariest decision</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Mon, 31 Jul 2023 19:35:10 +0000</pubDate>
      <link>https://forem.com/joshpollara/building-in-public-pricing-is-our-scariest-decision-176m</link>
      <guid>https://forem.com/joshpollara/building-in-public-pricing-is-our-scariest-decision-176m</guid>
      <description>&lt;p&gt;While building &lt;a href="https://terrateam.io"&gt;Terrateam&lt;/a&gt;, pricing have been some of the scariest decisions we’ve made. We have a lot of pride in what we’ve built. It doesn’t matter how many people say they like your product when you show it to them, the rubber meets the road when they have to give you their credit card.&lt;/p&gt;

&lt;p&gt;At first, we just tried to copy the pricing of companies that we thought were our competitors. We didn’t know what we were doing but they probably did. Take what they have and make a slight tweak to showcase what we think makes us special. We also asked for advice from a lot of people but it was hard to get an answer to “why” they recommended a price to us. A lot of the advice just seemed like “sounds like something that should cost $X”.&lt;/p&gt;

&lt;p&gt;To get our first paying customers, we went low. We looked at the cheapest non-free plan of our competitors and undercut it by 30%. And it worked! We started getting paying customers. But defining the value of your product purely based on the value of another product leaves an uneasy feeling. We didn’t want our product to just be a cheap copy of another. We had our own vision.&lt;/p&gt;

&lt;p&gt;We knew that we didn’t want to create a billion dollar company. We just wanted to solve our customers’ problems and make enough money to enjoy life. Early in our formation we read Company of One by Paul Jarvis. Company of One is for entrepreneurs that are happy creating a small, steadily growing, company. In other words: us. One of the biggest take-aways for us was about finding your market. A large company needs to appeal to a lot of people but a small company has more freedom to have a personality. We can be really appealing to a smaller group of people at the expense of being a turn off to others.&lt;/p&gt;

&lt;p&gt;We believe there are users that want a really good experience planning and applying their Terraform changes and will pay for support and SLAs. Our vision for Terrateam is a product for people who are happy never leaving GitHub for Terraform changes. We want very few touch-points with the product. Once it is setup, it should become invisible. In their day-to-day usage our customers see almost no branding. All Terrateam configuration and operations are done inside the repository or through pull requests. We don’t have a UI. Users create a pull request and see their Terraform plan in the comments and then they apply it in the pull request. There is no reason to leave. And we have a ton of features! So how much should that cost?&lt;/p&gt;

&lt;p&gt;We aren’t flashy. But we are feature rich. We are focused on a specific use case: Terraform plan and apply on GitHub. Being bootstrapped, we are very lean. We’ve implemented 70%-80% of the enterprise features of the competition but on a shoestring budget. We’re a small company that doesn’t have investors to repay. We want to stay small while maintaining our high quality of support, so we can’t have too many customers. Finally, we don’t even need to make a million dollars in revenue per year to be a success.&lt;/p&gt;

&lt;p&gt;That’s when we realized that we didn’t know who our competition was. There are the popular names in Terraform CI/CDs and we just assumed they were our competition. But they are rocket ships. They are after those enterprise contracts that are thousands of dollars per month. We don’t think your Terraform CI/CD should be so sophisticated that it should cost that much.&lt;/p&gt;

&lt;p&gt;With all that, the latest iteration on pricing is: $496/mo. We provide most of the enterprise features our users want at 1/10th the cost of the other options. With no GUI, the experience is more utilitarian, but you get the information you need in the place where you already are. We’ve only recently rolled out this change so we are still evaluating it. If history is any indicator of the future, we’ll be iterating on pricing again.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>terraform</category>
      <category>devops</category>
      <category>startup</category>
    </item>
    <item>
      <title>The Future of Terraform: ClickOps</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Thu, 22 Jun 2023 09:14:46 +0000</pubDate>
      <link>https://forem.com/joshpollara/the-future-of-terraform-clickops-2gj</link>
      <guid>https://forem.com/joshpollara/the-future-of-terraform-clickops-2gj</guid>
      <description>&lt;h2&gt;
  
  
  Quarter questions
&lt;/h2&gt;

&lt;p&gt;Every now and then it's important to step back from what we're doing and think about the future.  At &lt;a href="https://terrateam.io/"&gt;Terrateam&lt;/a&gt;, we like to ask a question each quarter to get our gears turning.  This quarter we asked:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What will Infrastructure as Code (IaC) look like in five years?&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure is slow to change
&lt;/h2&gt;

&lt;p&gt;Software infrastructure does not move quickly.  While greenfield projects may be able to take advantage of the latest trends, once software is made and in production, the lower bits don't change that much.&lt;/p&gt;

&lt;p&gt;It is difficult to migrate an existing project from DynamoDB to PostgreSQL or from JavaScript to Rust.  The number of banks still running on mainframes with COBOL might make you shudder.&lt;/p&gt;

&lt;p&gt;If the &lt;a href="https://oxide.computer"&gt;Oxide&lt;/a&gt; podcasts are any indication, things get more ossified further down the stack. In many cases, we prefer to add a layer to existing infrastructure to give us the new functionality we want rather than rewriting something from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  More people creating and modifying infrastructure is good
&lt;/h2&gt;

&lt;p&gt;More and more people are encoding their infrastructure in some way that can be tracked, audited, destroyed, and recreated. Terraform is the biggest contender along with Pulumi and the AWS CDK. These tools provide a way to provision and manage infrastructure.  And while they are very powerful, they can be daunting to learn.  There is a lot of desire to break the traditional silos of development and operations, empowering software engineers to manage their own infrastructure, but in many cases it's too much to ask them to become proficient in a whole new ecosystem.&lt;/p&gt;

&lt;p&gt;It's not uncommon for organizations to use templates in order to simplify the process.  Existing TACOS tools support this and tools like Backstage are also being used for this. Want to create a database and some compute?  Fill out a form and the code will be generated.  The learning curve is minimal.  The downside of templates is that they only work for creation. They are not much use for modifying existing code.  As the project grows, development will slow down as the team will have to learn Terraform, AWS CDK, or Pulumi.  ClickOps is the idea of providing GUIs for manipulating infrastructure where the output is code, such as Terraform HCL.&lt;/p&gt;

&lt;p&gt;There are a lot of ways that ClickOps can be achieved, but we think the any ClickOps solution should use HCL as its source and destination language. ClickOps tools can integrate into the existing rich ecosystem of Terraform tooling and advanced users can read and write Terraform code by hand if they wish.  With ClickOps, we can maximize the number of people who can comfortably manage infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  CDKTF, AWS CDK, and Pulumi are steps in the wrong direction
&lt;/h3&gt;

&lt;p&gt;According to &lt;a href="https://github.com/hashicorp/hcl"&gt;Hashicorp&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HCL is a toolkit for creating structured configuration languages that are both human- and machine-friendly, for use with command-line tools. Although intended to be generally useful, it is primarily targeted towards devops tools, servers, etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether or not one thinks Hashicorp's HCL is good at expressing infrastructure, it is in the least, a very limited language, which makes it hard to write convoluted code.  HCL is closer to other configuration languages like YAML or INI than a programming language.&lt;/p&gt;

&lt;p&gt;On the other hand, the AWS CDK and Pulumi allow one to write infrastructure in general purpose languages, such as TypeScript, Go or Python, This gives a lot more power to the user but also means the code representing their infrastructure can be quite complex.  HashiCorp is working on CDKTF to compete with AWS CDK and Pulumi.&lt;/p&gt;

&lt;p&gt;One perceived benefit of CDKs is that they allow multiple languages to be used in managing infrastructure, such as TypeScript, Go, Python or Java.  This has downsides as well. Documentation explodes as each language needs to be covered. APIs for each language can be auto generated, but auto generated APIs can feel awkward, so native APIs need to be maintained.  There is a lot of magic going on to make these general purpose languages generate declarative infrastructure which makes writing code for a CDK &lt;a href="https://ordina-jworks.github.io/cloud/2023/06/05/back-to-terraform.html"&gt;quite a different&lt;/a&gt; experience.  While it might be TypeScript one is writing, how they can use it is going to be different from what they are familiar with.&lt;/p&gt;

&lt;p&gt;The number of places that a bug can be encountered goes from just the Terraform CLI to now all the machinery between the CDK and Terraform.  Finding help becomes a challenge: is one trying to resolve a Python issue or a CDK issue? What if you have a bug in your TypeScript CDK and the answer found online is in response to a person asking in Go?  Can you even understand the answer if it requires details of that language?&lt;/p&gt;

&lt;p&gt;HashiCorp has tried to keep up with AWS CDK and Pulumi with CDKTF.  The way CDKTF works is the CDK code is compiled to a program which, when run, generates HCL, in JSON format.  CDKTF then runs the Terraform CLI on the generated HCL. For those that worked with JavaScript before source maps were a thing: compiling one language to another is a great way to solve some problems but it makes debugging difficult without a lot of tooling that can translate an issue in the&lt;br&gt;
compiled code to the source code.&lt;/p&gt;

&lt;p&gt;The multi-language approach makes creating tooling more challenging.  There has been a lot of tooling for Terraform built that consumes &lt;code&gt;.tf&lt;/code&gt; files, like linters, security scanning, cost estimation, etc. The CDKs make this a lot more difficult.  Not all of them can read HCL in JSON format, and even if they can, the developer experience of looking at an issue in generated code is not ideal.&lt;/p&gt;

&lt;p&gt;Platform engineering is trying to deliver the self-service tools teams want to consume to rapidly deploy all components of software.  While it may sound like a TypeScript developer would feel more empowered by writing their infrastructure in TypeScript, the reality is that it's a significant undertaking to learn to use these tools properly when all one wants to do is create or modify a few resources for their project.  This is also a common source of technical debt and fragility.  Most users will probably learn the minimal amount they need to in order to make progress in their project, and oftentimes this may not be the best solution for the longevity of a codebase.&lt;/p&gt;

&lt;p&gt;These tools are straddling an awkward line that is optimized for no-one. Traditional DevOps are not software engineers and software engineers are not DevOps.  By making infrastructure a software engineering problem, it puts all parties in an unfamiliar position.&lt;/p&gt;

&lt;p&gt;I am not saying no-one is capable of using these tools well.  The DevOps and software engineers I've worked with are more than capable.  This is a matter of attention. If you look at what a DevOps engineer has to deal with day-in and day-out, the nuances of TypeScript or Go will take a backseat.  And conversely, the nuances of, for example, a VPC will take a backseat to a software engineer delivering a new feature. The gap that the AWS CDK and Pulumi try to bridge is not optimized for anyone and this is how we get bugs, and more dangerously, security holes.&lt;/p&gt;

&lt;p&gt;On the surface, the AWS CDK, Pulumi, and CDKTF seem like a step forward, but they bring so much complexity without really solving the issue of making infrastructure easier to create, modify, and maintain, that they are anything but progress.&lt;/p&gt;

&lt;p&gt;The limits of HCL are also its strengths.  In this way, Hashicorp HCL shines. Those limitations mean it is easy for humans and computers to read, write, and understand.  With HCL, we allow humans to write Terraform code when it suits them but also allow computers to provide different views of that code as needed.&lt;/p&gt;

&lt;p&gt;Keeping IaC as code is vital. We do not want to rewrite source control, losing the rich ecosystem.  But we do want to allow the Terraform code to be manipulated in the way that suits that user best.&lt;/p&gt;

&lt;h3&gt;
  
  
  ClickOps enables more users
&lt;/h3&gt;

&lt;p&gt;ClickOps is the idea of providing GUIs for manipulating infrastructure which produce code.  There are a lot of ways that ClickOps can be achieved, but we think that any ClickOps solution should use HCL as its source and destination language.&lt;/p&gt;

&lt;p&gt;ClickOps tools can integrate into the existing rich ecosystem of Terraform tooling and advanced users can read and write Terraform code by hand if they wish. The goal here is to increase the number of users that can comfortably modify infrastructure while not alienating those who are already comfortable. We think HCL is a language that can cross that chasm, but not because it's easy for everyone to use but because it is a good balance of being consumable by humans and computers.  HCL is a great language for ClickOps.&lt;/p&gt;

&lt;p&gt;We want ClickOps that allows for the creation and modification of infrastructure without losing any of the value we get of IaC.  We still want to have pull requests before the change is applied.  We want to utilize the powerful ecosystem of Terraform tooling.  We want advanced users to be able to write Terraform code.&lt;/p&gt;

&lt;p&gt;Imagine a world where you have a service that knows how to read and write Terraform code.  It presents that code to the user as if it were an AWS console. They click through the GUI in order to make their changes and it writes the change out as Terraform code.  The user can then make a pull request from the change.  A reviewer then reads the code, as they would any other change.  Or maybe they prefer to use the service to visualize the pull request.&lt;/p&gt;

&lt;p&gt;Many users are familiar with the AWS console and would be able to make and review changes quickly, never having seen the Terraform code.  Users that are more comfortable in Terraform could look at the generated code.  We could create more than just write-once templates. An organization could have a template for creating their infrastructure in a testing environment. Once they are ready, they want to transition those changes to a production environment.  A service could understand the difference between these two environments, take the testing infrastructure code and produce new code that has the changes for production. This doesn't have to be a one-time change, but every time an infrastructure change is validated in testing it can transform it into production, making the appropriate changes.&lt;/p&gt;

&lt;p&gt;With ClickOps, we can have GUIs that have rich interfaces, preferably self documenting, enabling more users to work with infrastructure.  By providing powerful templates, wizards, and intuitive interfaces, users are more likely to make the right changes.  The end result is speed and stability. Software engineers can make infrastructure changes faster, not having to wait for support from operations, and they can also make them safer, the ClickOps platform providing guardrails on their changes.  By using HCL as the underlying language for all of this, we get the benefits of a GUI without losing the benefits of IaC.&lt;/p&gt;

&lt;h2&gt;
  
  
  The future of ClickOps
&lt;/h2&gt;

&lt;p&gt;We are curious what the community thinks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you think we are way off?&lt;/li&gt;
&lt;li&gt;Is the AWS CDK, Pulumi, and CDKTF actually the future?&lt;/li&gt;
&lt;li&gt;What is your experience with colleagues when they help manage their own infrastructure?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are hoping this blog post stirs up discussion. Even if you hate the idea, please let us know.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>cloud</category>
      <category>iac</category>
    </item>
    <item>
      <title>Terraform. GitOps. Lock Policies.</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Fri, 02 Jun 2023 09:49:09 +0000</pubDate>
      <link>https://forem.com/joshpollara/terraform-gitops-lock-policies-oh0</link>
      <guid>https://forem.com/joshpollara/terraform-gitops-lock-policies-oh0</guid>
      <description>&lt;h2&gt;
  
  
  What is Terrateam?
&lt;/h2&gt;

&lt;p&gt;Terrateam is Terraform continuous delivery. Purpose-built for GitHub with an expressive configuration file, popular third-party integrations, advanced features like OIDC, access controls, drift detection, and more. Self-Hosted and Cloud versions available.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;⭐ Star us on GitHub: &lt;a href="https://github.com/terrateamio/terrateam"&gt;https://github.com/terrateamio/terrateam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Announcing Lock Policies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Strict locking by default
&lt;/h3&gt;

&lt;p&gt;In a collaborative environment, it can be easy to forget to apply a change that has been merged or to merge a change that has been applied. Guaranteeing your infrastructure matches your code is one of the benefits of using Terrateam.&lt;/p&gt;

&lt;p&gt;When a change is applied in a pull request, Terrateam acquires a lock on the directory that changed and requires it be merged into the main branch.&lt;br&gt;
Similarly, if the change is merged, Terrateam acquires a lock on the directory and requires that it be applied.  A change is either merged or applied to acquire a lock, and the other operation must be done to release the lock.&lt;/p&gt;
&lt;h3&gt;
  
  
  Safety guarantees can get in the way
&lt;/h3&gt;

&lt;p&gt;Some directories are different.  For example, it is common for Terraform repositories to have both development environments and production environments described in them.  Using our &lt;a href="https://terrateam.io/docs/features/access-control"&gt;access control&lt;/a&gt; feature, Terrateam can be configured such that anyone can modify development but production is locked down.  Sometimes, to iterate faster, it makes sense to plan and apply development changes locally before making a pull request.&lt;/p&gt;

&lt;p&gt;Because the development environment is sometimes run via Terrateam and sometimes managed outside of Terrateam, the safety guarantees can get in the way. Terrateam is too strict in these scenarios.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lock Policies
&lt;/h3&gt;

&lt;p&gt;To support this workflow, we've introduced a new&lt;br&gt;
&lt;a href="https://terrateam.io/docs/features/workflows"&gt;workflow&lt;/a&gt; configuration called &lt;code&gt;lock_policy&lt;/code&gt;.  The &lt;code&gt;lock_policy&lt;/code&gt; option tells Terrateam under what situations it should acquire a&lt;br&gt;
lock.&lt;/p&gt;

&lt;p&gt;It has four modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;strict&lt;/code&gt; - This is the default and matches the current behavior.  If a user comments &lt;code&gt;terrateam apply&lt;/code&gt; in the pull request or the change is merged, Terrateam acquires a lock on the directory until the complimentary operation is performed.  We recommend all production directories keep this setting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apply&lt;/code&gt; - This instructs Terrateam to only acquire a lock if the directory has been applied in Terrateam (&lt;code&gt;terrateam apply&lt;/code&gt;).  The lock will be released once the change is merged.  If the change is just merged, Terrateam will not acquire a lock.  This is what should be used in the scenario described above. The development directories should be set to &lt;code&gt;lock_policy: apply&lt;/code&gt;, that way if they are applied outside of Terrateam, no lock is acquired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;merge&lt;/code&gt; - This instructs Terrateam to only acquire a lock if the directory has been merged.  The lock will be released when the change is applied (&lt;code&gt;terrateam apply&lt;/code&gt;).  This is useful if a pull request is used as a playground in development and then closed when done, rather than merging.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;none&lt;/code&gt; - Never acquire a lock.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, there are other situations where these settings make sense other than the ones described here.  But, be careful!  Locking is fundamental to how Terrateam keeps code and infrastructure synchronized.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;The locking policy is defined in the &lt;code&gt;workflows&lt;/code&gt; section.  To set &lt;code&gt;lock_policy&lt;/code&gt; to &lt;code&gt;apply&lt;/code&gt; for all directories &lt;code&gt;dev&lt;/code&gt; directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;tag_query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev in dir&lt;/span&gt;
    &lt;span class="na"&gt;lock_policy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apply&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docs
&lt;/h2&gt;

&lt;p&gt;Check out the &lt;a href="https://terrateam.io/docs"&gt;Terrateam Docs&lt;/a&gt; for more examples.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>cloud</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>Terrateam Self-Hosted: The Enterprise Atlantis Alternative</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Fri, 02 Jun 2023 09:43:17 +0000</pubDate>
      <link>https://forem.com/joshpollara/terrateam-self-hosted-the-enterprise-atlantis-alternative-599l</link>
      <guid>https://forem.com/joshpollara/terrateam-self-hosted-the-enterprise-atlantis-alternative-599l</guid>
      <description>&lt;h2&gt;
  
  
  What is Terrateam?
&lt;/h2&gt;

&lt;p&gt;Terrateam is Terraform continuous delivery. Purpose-built for GitHub with an expressive configuration file, popular third-party integrations, advanced features like OIDC, access controls, drift detection, and more. Self-Hosted and Cloud versions available.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;⭐ Star us on GitHub: &lt;a href="https://github.com/terrateamio/terrateam"&gt;https://github.com/terrateamio/terrateam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Announcing Terrateam Self-Hosted
&lt;/h2&gt;

&lt;p&gt;I'm excited to introduce the self-hosted version of Terrateam designed for customers that need to meet strict security and compliance requirements or just prefer to host their own deployment.&lt;/p&gt;

&lt;p&gt;Terrateam Self-Hosted provides the flexibility to deploy all of Terrateam to your own infrastructure giving you full control of your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature parity with Cloud
&lt;/h2&gt;

&lt;p&gt;Terrateam Self-Hosted is 100% identical to Terrateam Cloud. Full feature parity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;We're also releasing new pricing today. Here's the breakdown:&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Hosted
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Free forever&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Access to all features&lt;/li&gt;
&lt;li&gt;Unlimited users&lt;/li&gt;
&lt;li&gt;Unlimited usage&lt;/li&gt;
&lt;li&gt;Same-day business support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Terrateam Cloud
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Free for teams of two&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;$145/month (paid annually) or $175/month (paid monthly)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Access to all features&lt;/li&gt;
&lt;li&gt;Unlimited users&lt;/li&gt;
&lt;li&gt;Unlimited usage&lt;/li&gt;
&lt;li&gt;Same-day business support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Same-day business support
&lt;/h3&gt;

&lt;p&gt;Do we really have same-day business support? Even for Terrateam Self-Hosted?&lt;/p&gt;

&lt;p&gt;Yes, we really have same-day business support for all of our plans. When a customer reaches out to us for support, we see this as a golden opportunity to improve Terrateam. Whether that's by automating a process, updating our documentation, or creating a new feature request in our backlog, it's a way to improve the developer experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying Terrateam Self-Hosted
&lt;/h2&gt;

&lt;p&gt;Deploying Terrateam is really easy. There are two components of Terrateam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL Database&lt;/li&gt;
&lt;li&gt;Terrateam Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The easiest way to kick the tires is to use our &lt;a href="https://terrateam.io/docs/self-hosted"&gt;Docker Compose&lt;/a&gt;&lt;br&gt;
instructions. This gets you going in minutes. More production-grade deployment instructions (Kubernetes Helm Chart) are available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;

&lt;p&gt;The easiest way to get started is by signing up for &lt;a href="https://terrateam.io/docs/getting-started"&gt;Terrateam Cloud&lt;/a&gt;. If you need help onboarding please ping us on &lt;a href="https://terrateam.io/slack"&gt;Slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>cloud</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>CDKTF Frequently Asked Questions</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Thu, 23 Feb 2023 11:27:52 +0000</pubDate>
      <link>https://forem.com/joshpollara/cdktf-frequently-asked-questions-3jj6</link>
      <guid>https://forem.com/joshpollara/cdktf-frequently-asked-questions-3jj6</guid>
      <description>&lt;h2&gt;
  
  
  CDKTF Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does CDKTF mean?
&lt;/h3&gt;

&lt;p&gt;CDKTF stands for &lt;em&gt;Cloud Development Kit for Terraform&lt;/em&gt;.  The term &lt;em&gt;CDK&lt;/em&gt; is used to describe tools which allow managing cloud infrastructure using common programming languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  What problem does CDKTF solve?
&lt;/h3&gt;

&lt;p&gt;Developers can manage their infrastructure using familiar programming languages in place of the Terraform HCL language.  As well as using familiar programming languages, developers benefit from being able to use the ecosystem of their language of choice when developing infrastructure components.&lt;/p&gt;

&lt;p&gt;CDKTF was initially developed in&lt;br&gt;
&lt;a href="https://aws.amazon.com/blogs/opensource/announcing-cdk-for-terraform-on-aws/"&gt;collaboration&lt;/a&gt; with AWS which had released &lt;a href="https://aws.amazon.com/cdk/"&gt;AWS CDK&lt;/a&gt;.  AWS CDK turned out to be popular and developers really liked being able to work in their language of choice.&lt;/p&gt;

&lt;p&gt;AWS CDK and CDKTF are similar to Pulumi, which was developed with the idea of managing infrastructure using familiar programming languages.&lt;/p&gt;

&lt;p&gt;Key differences between the three offerings are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pulumi has its own engine for planning and applying changes&lt;/li&gt;
&lt;li&gt;AWS CDK generates AWS Cloud Assembly for planning and applying changes&lt;/li&gt;
&lt;li&gt;CDKTF generates Terraform code (HCL) for planning and applying changes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What languages does CDKTF support?
&lt;/h3&gt;

&lt;p&gt;CDKTF can be written in the following languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf/api-reference/typescript"&gt;TypeScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf/api-reference/python"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf/api-reference/java"&gt;Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf/api-reference/csharp"&gt;C#&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf/api-reference/go"&gt;Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Is CDKTF production ready?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;.  On &lt;a href="https://www.hashicorp.com/blog/cdk-for-terraform-now-generally-available"&gt;Aug 1&lt;br&gt;
2022&lt;/a&gt;, HashiCorp announced that CDKTF is Generally Available and ready for production usage.  CDKTF is still a maturing technology, however, you should feel confident using it in a production environment.&lt;/p&gt;
&lt;h3&gt;
  
  
  What are the advantages of CDKTF?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Developers who are familiar with programming languages but not HCL can contribute to infrastructure changes.&lt;/li&gt;
&lt;li&gt;Being able to express infrastructure in TypeScript, Python, Java, C#, or Go allows for leveraging the ecosystem of those languages.&lt;/li&gt;
&lt;li&gt;The development environments (editors, IDEs, language servers, testing frameworks) are very mature.&lt;/li&gt;
&lt;li&gt;Programming languages are more powerful than HCL.&lt;/li&gt;
&lt;li&gt;More people are familiar with programming languages than HCL.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What are the disadvantages of CDKTF?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CDKTF is still maturing.  The underlying engine which executes CDKTF is robust. One needs to have implementations of providers and resources in the CDKTF ecosystem, which is still growing.&lt;/li&gt;
&lt;li&gt;Documentation, especially around providers, is lacking.  One might have to read code in order to understand how to use a provider.&lt;/li&gt;
&lt;li&gt;CDKTF is complicated.  It requires converting code written in a programming language to HCL, which you could have written yourself.&lt;/li&gt;
&lt;li&gt;CDKTF also adds new concepts (for example "stacks"), making it not a direct one-to-one translation of Terraform.  This means those developers who are familiar with Terraform will need to learn CDKTF before they are effective.&lt;/li&gt;
&lt;li&gt;With great power comes great responsibility.  Programming languages are much more expressive than HCL.  While HCL has its limitations, these limitations also mean the code has a ceiling of complexity.  Programming languages do not have the same constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Should I use CDKTF?
&lt;/h3&gt;

&lt;p&gt;Like most technical decisions: it depends.&lt;/p&gt;

&lt;p&gt;Whether or not CDKTF is the right decision for you is something you need to determine.&lt;/p&gt;

&lt;p&gt;Here are some factors you should consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is using CDKTF going to make it easier for developers in my organization to contribute infrastructure changes?&lt;/li&gt;
&lt;li&gt;Do I have the &lt;a href="https://mcfunley.com/choose-boring-technology"&gt;innovation tokens&lt;/a&gt; to use a maturing technology?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;CDKTF will continue to be developed and improved by HashiCorp, so if you like where it is now, it is probably a good decision.&lt;/p&gt;
&lt;h3&gt;
  
  
  Does CDTKTF require Terraform Cloud?
&lt;/h3&gt;

&lt;p&gt;No.  You can use CDKTF anywhere.&lt;/p&gt;
&lt;h3&gt;
  
  
  What language is CDKTF implemented in?
&lt;/h3&gt;

&lt;p&gt;The CDKTF CLI is implemented in TypeScript.  Providers and resources are implemented in TypeScript as well.  &lt;a href="https://aws.github.io/jsii/"&gt;jsii&lt;/a&gt; is used to compile the providers and resources to the supported languages.&lt;/p&gt;
&lt;h3&gt;
  
  
  How does CDKTF work?
&lt;/h3&gt;

&lt;p&gt;The high-level process of how CDKTF works is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer writes code in their preferred programming language that CDKTF supports.&lt;/li&gt;
&lt;li&gt;The code must create an instance of an "app".&lt;/li&gt;
&lt;li&gt;The developer creates "stacks", "providers", and "resources" and adds them to the "app".  This creates an internal representation of the infrastructure which can be turned into something else using the &lt;code&gt;synth&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;After constructing the infrastructure objects, at the end the developer must call the &lt;code&gt;synth&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;The user then executes &lt;code&gt;cdktf diff&lt;/code&gt;, &lt;code&gt;cdktf deploy&lt;/code&gt;, or &lt;code&gt;cdktf synth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The CDKTF CLI runs the code the developer wrote and the call to &lt;code&gt;synth&lt;/code&gt; knows how to convert the app (which has the stack and resources and providers added to it) to the JSON representation of HCL.&lt;/li&gt;
&lt;li&gt;The CDKTF CLI can then run &lt;code&gt;terraform plan&lt;/code&gt; or &lt;code&gt;terraform apply&lt;/code&gt; on the HCL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is possible that &lt;code&gt;cdktf diff&lt;/code&gt; and &lt;code&gt;cdktf deploy&lt;/code&gt; could perform the translation to Terraform HCL and execution in-memory, however &lt;code&gt;cdktf synth&lt;/code&gt; will always produce Terraform HCL in a directory that you can manually run the Terraform CLI against.&lt;/p&gt;

&lt;p&gt;Considering the following CDKTF code in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import * as Null from './.gen/providers/null';

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new Null.provider.NullProvider(this, 'test-provider');
    new Null.resource.Resource(this, 'test');
  }
}

const app = new App();
new MyStack(app, "cdktf-stack1");
app.synth();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the last line, &lt;code&gt;app.synth()&lt;/code&gt;, the entire app has been created and all providers and resources have been added to the stack.  The &lt;code&gt;synth&lt;/code&gt; call can then&lt;br&gt;
produce Terraform HCL files and the CDKTF CLI can execute &lt;code&gt;terraform plan&lt;/code&gt; or &lt;code&gt;terraform apply&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  How can I convert Terraform code to CDKTF?
&lt;/h3&gt;

&lt;p&gt;The CDKTF CLI can convert Terraform files using &lt;a href="https://developer.hashicorp.com/terraform/cdktf/cli-reference/commands#convert"&gt;cdktf&lt;br&gt;
convert&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is an app?
&lt;/h3&gt;

&lt;p&gt;CDKTF code constructs an object called "app".  This represents all of the infrastructure that will be generated in CDKTF.  Stacks will be added to the app.  And providers and resources will be added to the stack.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is a stack?
&lt;/h3&gt;

&lt;p&gt;Stacks represent a collection of infrastructure configuration that will be managed.  You can think of them as somewhere between Terraform modules and workspaces.  You might use a stack to represent the infrastructure in an AWS region and then create an instance of that stack per region.  For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string, region: string) {
    super(scope, id);

    // define resources here
  }
}

const app = new App();
new MyStack(app, "cdktf-stack1", "us-east-1");
new MyStack(app, "cdtff-stack2", "us-west-1");
app.synth();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Where can I learn more about CDKTF?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cdktf"&gt;CDK for Terraform Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hashicorp/terraform-cdk"&gt;&lt;code&gt;hashicorp/terraform-cdk repository&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>sre</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Using Multiple AWS IAM Roles</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Fri, 17 Feb 2023 14:48:42 +0000</pubDate>
      <link>https://forem.com/joshpollara/using-multiple-aws-iam-roles-2pm6</link>
      <guid>https://forem.com/joshpollara/using-multiple-aws-iam-roles-2pm6</guid>
      <description>&lt;h3&gt;
  
  
  Access Control with IAM
&lt;/h3&gt;

&lt;p&gt;One of the most important, and oftentimes most confusing, aspects of cloud infrastructure is access control. AWS IAM provides a way to secure access to AWS resources.&lt;/p&gt;

&lt;p&gt;IAM roles are a key concept in AWS IAM that allow users to delegate access to AWS resources to other AWS accounts, AWS services, and external identities.&lt;/p&gt;

&lt;p&gt;Using multiple AWS IAM roles in combination with Terraform allows you to manage access to resources in a more secure and scalable manner.&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM Roles
&lt;/h3&gt;

&lt;p&gt;AWS IAM roles that allow you to grant permissions to one or more AWS resources to a specific entity. An entity is just a way to reference another AWS account, AWS service, or third-party.&lt;/p&gt;

&lt;p&gt;It's important to understand that IAM roles are not associated with specific users or groups. IAM roles are only associated with specific policies that grant access to AWS resources.&lt;/p&gt;

&lt;p&gt;When an entity assumes an IAM role, it receives the permissions that are defined in the policy attached to that IAM role.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of IAM Roles
&lt;/h3&gt;

&lt;p&gt;There are many advantages when using IAM roles vs. other access controls.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static credentials are not required&lt;/li&gt;
&lt;li&gt;Ability to grant permissions to third-parties without the need of a dedicated IAM user&lt;/li&gt;
&lt;li&gt;Granular permissions for a specific use case&lt;/li&gt;
&lt;li&gt;Leverage ephemeral resources like EC2 instances and Lambda functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Using Multiple IAM Roles with Terraform
&lt;/h3&gt;

&lt;p&gt;There are a few different ways to leverage AWS IAM roles with the Terraform AWS provider.&lt;/p&gt;

&lt;p&gt;One common way is to use the &lt;code&gt;assume_role&lt;/code&gt; parameter to specify which IAM role should be assumed&lt;br&gt;
when running the Terraform CLI. This can be defined on the &lt;code&gt;provider&lt;/code&gt; or &lt;code&gt;resource&lt;/code&gt; level.&lt;/p&gt;

&lt;p&gt;A real-world example is to use separate IAM roles for a &lt;code&gt;production&lt;/code&gt; and &lt;code&gt;qa&lt;/code&gt; environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/production-role"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;role_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/qa-role"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once defined, you can specify which provider block to use for each resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-4c55b159cbfafe1fe"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;provider&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qa&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another common way to leverage AWS IAM roles with the Terraform AWS provider is by using the AWS CLI to assume a role before executing Terraform commands. The &lt;code&gt;aws sts assume-role&lt;/code&gt; command provides a very easy way to return a set of temporary security credentials for a specific IAM role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws sts assume-role \
--role-arn "arn:aws:iam::123456789012:role/qa-role" \
--role-session-name qa-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS will return a set of temporary credentials that can then be used to create &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; environment variables which the Terraform AWS provider consumes. This is how&lt;br&gt;
the Terrateam GitHub Action assumes a user-defined IAM role. This method doesn't require you to specify &lt;code&gt;role_arn&lt;/code&gt; in your Terraform code.&lt;/p&gt;

&lt;p&gt;By using separate IAM roles in each environment, you have the ability to define each role with its own set of permissions. The &lt;code&gt;qa&lt;/code&gt; environment IAM role would not need access to the &lt;code&gt;production&lt;/code&gt; environment&lt;br&gt;
and vice versa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benefits of Using Multiple IAM Roles with Terraform
&lt;/h3&gt;

&lt;p&gt;As you can already start to see, there are many benefits of using multiple IAM roles with Terraform.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Security: Separate IAM roles improves your security posture by limiting access to your AWS resources only to entities that require access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simplicity: It's easier to understand which entities have access to AWS resources by using separate IAM roles for different environments. Having the ability to easily manage access to resources based on&lt;br&gt;
internal needs helps keep you more organized and secure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compliance: Industry standards, best practices, and various other regulations like HIPAA and GDPR often require having the ability to enforce least privilege access to infrastructure. Separate IAM roles&lt;br&gt;
give you the building blocks to satisfy these requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexibility: Having the ability to create granular access rules based on the needs of an organization creates flexibility and scalability for engineering teams.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auditing: Monitoring account activity by separate IAM roles for each environment, entity, and third-party gives you the ability to easily audit access to resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Using Multiple IAM Roles with Terrateam
&lt;/h3&gt;

&lt;p&gt;Using multiple IAM roles in a Terraform repository with Terrateam is easy to accomplish by creating simple configuration in your &lt;code&gt;.terrateam/config.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take the following directory structure as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;josh@elmer:~/terraform &lt;span class="nv"&gt;$ &lt;/span&gt;tree
&lt;span class="nb"&gt;.&lt;/span&gt;
├── modules
│   └── ec2
│       └── v1
│           └── main.tf
├── production
│   └── main.tf
└── qa
    └── main.tf

5 directories, 3 files
josh@elmer:~/terraform &lt;span class="nv"&gt;$ &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this Terraform repository, we have three directories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;modules&lt;/code&gt;: Custom-written Terraform modules that's referenced throughout the repository&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;production&lt;/code&gt;: Defined Terraform resources for the Production environment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;qa&lt;/code&gt;: Defined Terraform resources for the QA environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An ideal workflow for this repository layout is to use separate IAM roles for each environment. By creating a &lt;code&gt;.terrateam/config.yml&lt;/code&gt; at the root of the repository, one can safely assume separate IAM roles&lt;br&gt;
before any Terraform CLI commands are issued.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;tag_query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dir:production&lt;/span&gt;
    &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oidc&lt;/span&gt;
        &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
        &lt;span class="na"&gt;role_arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::123456789012:role/terrateam-production-role"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;plan&lt;/span&gt;
    &lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oidc&lt;/span&gt;
        &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
        &lt;span class="na"&gt;role_arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::123456789012:role/terrateam-production-role"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apply&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;tag_query&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dir:qa&lt;/span&gt;
    &lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oidc&lt;/span&gt;
        &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
        &lt;span class="na"&gt;role_arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::123456789012:role/terrateam-qa-role"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;plan&lt;/span&gt;
    &lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;oidc&lt;/span&gt;
        &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
        &lt;span class="na"&gt;role_arn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::123456789012:role/terrateam-qa-role"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;init&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apply&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above configuration will execute the following steps in your isolated Terrateam GitHub Actions runtime environment&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Issue a secure token using the official GitHub OIDC Identity Provider. This token is used to authenticate against your AWS account. After a successful authentication, the Terrateam action will&lt;br&gt;
automatically assume the IAM role defined in the &lt;code&gt;role_arn&lt;/code&gt; configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After successful authentication to AWS, Terrateam will execute an &lt;code&gt;aws sts&lt;/code&gt; command in the GitHub Actions runtime environment to generate short-lived credentials for the IAM role defined&lt;br&gt;
in the &lt;code&gt;role_arn&lt;/code&gt; depending on which directory contains Terraform-related changes in the pull request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute the necessary Terraform CLI commands in the directory where the Terraform-code change lies&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform plan&lt;/code&gt; or &lt;code&gt;terraform apply&lt;/code&gt; depending on the operation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Separate IAM roles are defined and used by leveraging Terrateam &lt;a href="https://terrateam.io/docs/features/workflows" rel="noopener noreferrer"&gt;workflows&lt;/a&gt;. With custom workflows, the user can define many customizations to the steps&lt;br&gt;
Terrateam will take depending on what file, directory, or workspace is modified in a pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Multiple AWS IAM roles with Terraform allows your team to properly manage access to your AWS resources in many environments. This is instrumental in achieving a proper security posture and creates a strong&lt;br&gt;
foundation for scalable IAM. With the help of Terrateam, you can create and enforce specific IAM roles to be used against resources laid out in your Terraform repository.&lt;/p&gt;

&lt;p&gt;Give &lt;a href="https://terrateam.io" rel="noopener noreferrer"&gt;Terrateam&lt;/a&gt; a try and start leveraging multiple IAM roles with &lt;a href="https://terrateam.io/docs/features/oidc" rel="noopener noreferrer"&gt;OIDC&lt;/a&gt; today.&lt;/p&gt;

</description>
      <category>sideprojects</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Creating an AWS Lambda Function with Terraform</title>
      <dc:creator>Josh Pollara</dc:creator>
      <pubDate>Thu, 16 Feb 2023 12:18:06 +0000</pubDate>
      <link>https://forem.com/joshpollara/creating-an-aws-lambda-function-with-terraform-158d</link>
      <guid>https://forem.com/joshpollara/creating-an-aws-lambda-function-with-terraform-158d</guid>
      <description>&lt;h2&gt;
  
  
  Creating an AWS Lambda Function with Terraform
&lt;/h2&gt;

&lt;p&gt;Writing the proper Terraform code for an AWS Lambda function may seem like a daunting task but it doesn't have to be.&lt;/p&gt;

&lt;p&gt;While there are a few moving parts to the process, I'll explain how to deploy a Lambda function to a VPC that can access other resources within your VPC using&lt;br&gt;
appropriate IAM permissions.&lt;/p&gt;

&lt;p&gt;Full code example here: &lt;a href="https://github.com/terrateamio/terraform-aws-lambda-example"&gt;https://github.com/terrateamio/terraform-aws-lambda-example&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;main.tf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The below resources are examples and should be adjusted to suit your needs. The code can be added to your Terraform repository in a file named &lt;code&gt;main.tf&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Provider
&lt;/h3&gt;

&lt;p&gt;Add the &lt;code&gt;aws&lt;/code&gt; provider&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 4.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  VPC
&lt;/h3&gt;

&lt;p&gt;Create a new VPC&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_vpc"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;
  &lt;span class="nx"&gt;enable_dns_hostnames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;enable_dns_support&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-vpc"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Subnets
&lt;/h3&gt;

&lt;p&gt;Create at least one subnet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_subnet"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;availability_zone&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-west-2b"&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-subnet"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Group
&lt;/h3&gt;

&lt;p&gt;Create a security group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-sg"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IAM Role and Policy
&lt;/h3&gt;

&lt;p&gt;Create an IAM role and policy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-role"&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda.amazonaws.com"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_policy"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-policy"&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"logs:CreateLogGroup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"logs:CreateLogStream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"logs:PutLogEvents"&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:logs:*:*:*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
      &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"ec2:CreateNetworkInterface"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ec2:DescribeNetworkInterfaces"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ec2:DeleteNetworkInterface"&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_policy&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This IAM role and policy allows your Lambda function to create, describe, and delete network interfaces, and create and push logs to CloudWatch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Function
&lt;/h3&gt;

&lt;p&gt;The last step is to create your actual Lambda function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;function_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"example-lambda"&lt;/span&gt;
  &lt;span class="nx"&gt;filename&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"lambda_function_payload.zip"&lt;/span&gt;
  &lt;span class="nx"&gt;source_code_hash&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filebase64sha256&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lambda_function_payload.zip"&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;handler&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"index.handler"&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;runtime&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nodejs14.x"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;security_group_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Changes
&lt;/h3&gt;

&lt;p&gt;View the changes to be deployed to your AWS account&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init
$ terraform validate
$ terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Apply Changes
&lt;/h3&gt;

&lt;p&gt;Create the AWS resources defined in your &lt;code&gt;main.tf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these steps, you can deploy an AWS Lambda function to a VPC with all the proper IAM permissions. Check out &lt;a href="https://terrateam.io"&gt;Terrateam&lt;/a&gt; to learn how to safely &lt;code&gt;plan&lt;/code&gt; and &lt;code&gt;apply&lt;/code&gt; infrastructure changes alongside other code and with your teammates.&lt;/p&gt;

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