<?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>DEV Community: Thomas Decaux</title>
    <description>The latest articles on DEV Community by Thomas Decaux (@ebuildy).</description>
    <link>https://dev.to/ebuildy</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%2F1938015%2Fc5974b55-451f-44cd-8ed8-8030194461a2.png</url>
      <title>DEV Community: Thomas Decaux</title>
      <link>https://dev.to/ebuildy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ebuildy"/>
    <language>en</language>
    <item>
      <title>Use Terraform module from a private git project with Atlantis</title>
      <dc:creator>Thomas Decaux</dc:creator>
      <pubDate>Fri, 16 Aug 2024 14:28:45 +0000</pubDate>
      <link>https://dev.to/ebuildy/use-terraform-module-from-a-private-git-project-with-atlantis-18ak</link>
      <guid>https://dev.to/ebuildy/use-terraform-module-from-a-private-git-project-with-atlantis-18ak</guid>
      <description>&lt;p&gt;Let's use Terraform modules hosted in private repository on Gitlab - &lt;br&gt;
&lt;a href="https://developer.hashicorp.com/terraform/language/modules/sources#generic-git-repository" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/language/modules/sources#generic-git-repository&lt;/a&gt; with Atlantis for the CI/CD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.runatlantis.io/" rel="noopener noreferrer"&gt;https://www.runatlantis.io/&lt;/a&gt; is a tool for collaborating on Terraform, enables developers and operators to run terraform plan and apply directly from Terraform pull requests. Atlantis then comments back on the pull request with the output of the commands.&lt;/p&gt;

&lt;p&gt;Here the components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1nqbrh8yk5qlcip3ch7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1nqbrh8yk5qlcip3ch7.png" alt="Diagram terraform atlantis git module" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;p&gt;Best practices suggest always using a registry, but there are situations where you might prefer to use a Git repository as a module source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publishing on a registry requires more effort, such as setting up a CI/CD pipeline&lt;/li&gt;
&lt;li&gt;You need to set up, configure, secure, and maintain a registry&lt;/li&gt;
&lt;li&gt;The development workflow is slower because you have to wait for the module to be published&lt;/li&gt;
&lt;li&gt;You might not want to publish a module under active development on a registry, but you still want to use it from a root module for testing purposes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Atlantis is running on kubernetes, git credentials username / password are provided by 2 env variables sourced from a kubernetes secret.&lt;/p&gt;

&lt;p&gt;We dont want to write a &lt;code&gt;.git-credentials&lt;/code&gt; file (see &lt;a href="https://www.runatlantis.io/docs/server-configuration#write-git-creds" rel="noopener noreferrer"&gt;https://www.runatlantis.io/docs/server-configuration#write-git-creds&lt;/a&gt;) because it saves the credentials in plaintext on disk!&lt;/p&gt;
&lt;h2&gt;
  
  
  Terraform code
&lt;/h2&gt;

&lt;p&gt;This is the easiest part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module "vpc" {
  source = "git::https://gitlab.com/company/terraform/vpc.git?depth=1&amp;amp;ref=v1.2.0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will not work, because there is no authentication configuration!&lt;/p&gt;

&lt;h2&gt;
  
  
  Atlantis code
&lt;/h2&gt;

&lt;p&gt;Many solutions found on the internet suggest configuring Git globally to allow Terraform to clone the repository. While this might work, setting up a global configuration is not a good idea.&lt;/p&gt;

&lt;p&gt;Since Atlantis is a shared service, we want to restrict access so that only our Atlantis workflow can fetch the Terraform module.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git credentials helper
&lt;/h3&gt;

&lt;p&gt;Here the magic! Many cli tools like docker, kubectl, git ... propose a credential manager and contexts:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/docs/gitcredentials#_credential_contexts" rel="noopener noreferrer"&gt;https://git-scm.com/docs/gitcredentials#_credential_contexts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we must configure a credentials helper (just a small bash code) for context: "&lt;a href="https://gitlab.com/company/terraform" rel="noopener noreferrer"&gt;https://gitlab.com/company/terraform&lt;/a&gt;" to give username and password sourced from env variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "username=${ATLANTIS_GITLAB_USER}";
echo "password=${ATLANTIS_GITLAB_TOKEN}";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple shell script that output a .env format. You can use another gitlab service account, or even better &amp;amp; secure, generate a password with vault generator &lt;a href="https://github.com/splunk/vault-plugin-secrets-gitlab" rel="noopener noreferrer"&gt;https://github.com/splunk/vault-plugin-secrets-gitlab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In our scenario, we want to configure this only for the current Atlantis workflow, fortunately, Git allows us to configure credentials using environment variables!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If GIT_CONFIG_COUNT is set to a positive number, all environment pairs GIT_CONFIG_KEY_ and GIT_CONFIG_VALUE_ up to that number will be added to the process’s runtime configuration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Atlantis workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflows:
  my-workflow:
    plan:
      steps:
        - env:
            name: GIT_CONFIG_COUNT
            value: "1"
        - env:
            name: GIT_CONFIG_KEY_0
            value: "credential.https://gitlab.com/company/terraform.helper"
        - env:
            name: GIT_CONFIG_VALUE_0
            value: |
              !f() { echo "username=${ATLANTIS_GITLAB_USER}"; echo "password=${ATLANTIS_GITLAB_TOKEN}"; }; f
        - init
        - plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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