{"id":286,"date":"2022-07-20T15:07:12","date_gmt":"2022-07-20T20:07:12","guid":{"rendered":"https:\/\/cloudlearning365.com\/?p=286"},"modified":"2022-10-14T09:40:01","modified_gmt":"2022-10-14T14:40:01","slug":"terraform-init-failed-to-download-providers","status":"publish","type":"post","link":"https:\/\/cloudlearning365.com\/?p=286","title":{"rendered":"Terraform init failed to download providers"},"content":{"rendered":"\n<p>One of our customers are looking to use Aviatrix to automatic their self-service process for AWS China region. <\/p>\n\n\n\n<p>The issue they are running into, was the terraform init would fail 50% of time. Is there anything we can do to help in this situation?<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">What are providers?<\/h2>\n\n\n\n<p>Terraform uses plug-ins called providers to translate terraform definition to API calls to AWS\/Azure\/GCP or Aviatrix controller. The providers are compiled binary files for specific platform.<\/p>\n\n\n\n<p>These binaries are published on <a href=\"https:\/\/releases.hashicorp.com\">https:\/\/releases.hashicorp.com<\/a><br>You may find familiar providers for AWS\/Azure as highlighted below, as well as Aviatrix<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"565\" height=\"849\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-24.png\" alt=\"\" class=\"wp-image-287\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-24.png 565w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-24-200x300.png 200w\" sizes=\"auto, (max-width: 565px) 100vw, 565px\" \/><\/figure>\n\n\n\n<p>Once you click on the aviatrix link, you will be presented to various different versions of aviatrix providers. Aviatrix is constantly improving it&#8217;s product and adding new features, as such new APIs are added\/modified\/removed, which resulting different versions of terraform providers. Refer to <a href=\"https:\/\/registry.terraform.io\/providers\/AviatrixSystems\/aviatrix\/latest\/docs\/guides\/release-compatibility\">this link<\/a> for the relationship between Aviatrix provider and Aviatrix controller. It&#8217;s important to match the Aviatrix provider to version of your controller.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"769\" height=\"838\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-25.png\" alt=\"\" class=\"wp-image-288\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-25.png 769w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-25-275x300.png 275w\" sizes=\"auto, (max-width: 769px) 100vw, 769px\" \/><\/figure>\n\n\n\n<p>Understanding with newer version of terraform (v0.13 and above), the required provider section will define which version of providers terraform will use<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform {\n  required_providers {\n    aviatrix = {\n      source  = \"AviatrixSystems\/aviatrix\"\n      <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">version = \"~&gt; 2.20.1\"<\/mark>\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>It&#8217;s also important to understand the effect of <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">version = &#8220;&#8221;<\/mark> portion<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>version = &#8220;2.21.1-6.6.ga&#8221;  will download *exact* version: 2.21.1-6.6.ga<\/li><li>version = &#8220;~&gt; 2.20.<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">1<\/mark>&#8221; Only the <em>rightmost<\/em> version can be incremented. In the screenshot above, we have version 2.20.<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">0<\/mark>, 2.20.<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">1<\/mark>, 2.20.<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">2<\/mark>, and 2.20.<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">3<\/mark>. As it cannot change the left portion: 2.20, it will download latest version: 2.20.3<\/li><li>version = &#8220;&gt;= 2.18.0, &lt; 2.20.0&#8221; will download latest version that will immediately lower than 2.0.0 AND higher or equal to 1.2.0 (Can you figure out which version this would be for Aviatrix? Read further to find answer)<\/li><\/ul>\n\n\n\n<p>If you further click through a version in release.hashicorp.com page, you will see list of .zip files ended with various platform names. As you can see some are for freebsd, and some are for linux and some are for windows, and we have 386\/arm\/am64 architecture etc.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"804\" height=\"831\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-27.png\" alt=\"\" class=\"wp-image-293\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-27.png 804w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-27-290x300.png 290w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-27-768x794.png 768w\" sizes=\"auto, (max-width: 804px) 100vw, 804px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">What does <strong>terraform init<\/strong> do in the background?<\/h2>\n\n\n\n<p>By default, terraform will look at your configuration, find out what provider and which version you intended to use, also figure out what OS and CPU architecture you are on, then it will download specific zip file and extract it under your terraform projects folder.<\/p>\n\n\n\n<p>Eg: I&#8217;m running Ubuntu 64 bits under WSL2 and I have this version restriction: version = &#8220;&gt;= 2.18.0, &lt; 2.20.0&#8221;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Initializing provider plugins...\n- Finding aviatrixsystems\/aviatrix versions matching \"&gt;= 2.18.0, &lt; 2.20.0\"...\n- Installing aviatrixsystems\/aviatrix v2.19.5...\n- Installed aviatrixsystems\/aviatrix v2.19.5 (signed by a HashiCorp partner, key ID 6105FDDA096C7419)<\/code><\/pre>\n\n\n\n<p>Under current terraform folder &#8220;project1&#8221; it created following structure<\/p>\n\n\n\n<p>\/project1.terraform\/providers\/registry.terraform.io\/aviatrixsystems\/aviatrix\/2.19.5\/linux_amd64<\/p>\n\n\n\n<p>This is called <strong>Unpacked layout<\/strong>, as the zip file was extracted, in the format of: HOSTNAME\/NAMESPACE\/TYPE\/VERSION\/TARGET<br>Where:<br>HOSTNAME = registry.terraform.io<br>NAMESPACE = aviatrixsystems<br>TYPE = aviatrix<br>VERSION = 2.19.5<br>TARGET = linux_amd64<\/p>\n\n\n\n<p>Structure of the folder:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"416\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-28-1024x416.png\" alt=\"\" class=\"wp-image-294\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-28-1024x416.png 1024w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-28-300x122.png 300w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-28-768x312.png 768w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-28.png 1064w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Running tcpdump while doing terraform init shows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Query against registry.terraform.io <\/li><li>Query against github.com<\/li><li>Query against objects.githubusercontent.com<\/li><li>As well as consequent HTTPs connections against them<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"388\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-1024x388.png\" alt=\"\" class=\"wp-image-295\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-1024x388.png 1024w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-300x114.png 300w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-768x291.png 768w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-1536x582.png 1536w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-29-2048x776.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo tcpdump -i eth0 -s 65535 -w \/mnt\/c\/gitrepos\/project1\/project1.pcap<\/code><\/pre>\n\n\n\n<p>Given the users are in China and certain DNS query and HTTPs connections may not work as desired, we need to find a way to enable customers to accomplish their self-service portal.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configure Terraform to use pre-downloaded providers<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Use Terraform to download providers<\/h3>\n\n\n\n<p>In terraform v0.13 and above, a <a href=\"https:\/\/www.terraform.io\/cli\/commands\/providers\/mirror\">new command<\/a> has been added to help download the required providers.<\/p>\n\n\n\n<p>For China users, they will need to create a jumpbox that have no problem talking to resolve registry.terraform.io and github.com and objects.githubusercontent.com, and consequently connect to them via HTTPS.<\/p>\n\n\n\n<p>On this jumpbox, create a folder with terraform code like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform {\n  required_providers {\n    aviatrix = {\n      source  = \"AviatrixSystems\/aviatrix\"\n      <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">version = \"2.20.1\"<\/mark>\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Within the folder, run following command, following example is in Linux environment, and assuming that the jumpbox as the same OS\/CPU Architecture as production terraform instance.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform providers mirror &#91;options] &lt;target-dir&gt;\n\nEg:\nterraform providers mirror <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">\/mnt\/c\/gitrepos\/providers<\/mark><\/code><\/pre>\n\n\n\n<p>You will observe the folder structure created under \/mnt\/c\/gitrepos\/providers looks like:<\/p>\n\n\n\n<p>C:\\gitrepos\\providers\\registry.terraform.io\\aviatrixsystems\\aviatrix<br>HOSTNAME\/NAMESPACE\/TYPE\/terraform-provider_VERSION_TARGET_TYPE.zip<\/p>\n\n\n\n<p>Where:<br>HOSTNAME = registry.terraform.io<br>NAMESPACE = aviatrixsystems<br>TYPE = aviatrix<br>VERSION_TARGET_TYPE = 2.19.5_linux_amd64<\/p>\n\n\n\n<p>This is called <strong>Packed layout<\/strong>, as the providers are download as ZIP not extracted.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"428\" src=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-30-1024x428.png\" alt=\"\" class=\"wp-image-297\" srcset=\"https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-30-1024x428.png 1024w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-30-300x125.png 300w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-30-768x321.png 768w, https:\/\/cloudlearning365.com\/wp-content\/uploads\/2022\/07\/image-30.png 1414w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I&#8217;ve modified my version and ran it three times, note, it downloaded 2.19.5, 2.20.1, 2.22.1, and each have corresponding .json file. Content of 2.19.5.json:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"archives\": {\n    \"linux_amd64\": {\n      \"hashes\": &#91;\n        \"h1:9MN1U\/vRiPWBnUNwnF12uSR4pgnVpWoilNahBTWdaLM=\"\n      ],\n      \"url\": \"terraform-provider-aviatrix_2.19.5_linux_amd64.zip\"\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Content of inde.json, acting as a lookup index for all versions:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"versions\": {\n    \"2.19.5\": {},\n    \"2.20.1\": {},\n    \"2.22.1\": {}\n  }\n}<\/code><\/pre>\n\n\n\n<p><strong>terraform providers mirror<\/strong> command will manage the download of provider ZIP files and these .json files.<\/p>\n\n\n\n<p>Note: If the jumpbox is in different OS\/Architecture as the instance running terraform, you can use -platform=OS_ARCH switch to force terraform to download specific OS\/Architecture binary to target folder. <\/p>\n\n\n\n<p>Eg:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform providers mirror <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">-platform linux_amd64<\/mark> \/mnt\/c\/gitrepos\/providers<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configure terraform to use the download providers<\/h3>\n\n\n\n<p>Assume you have downloaded all necessary providers under \/mnt\/c\/gitrepos\/providers, you have to tell terraform to use this folder instead of trying to download provider binaries from Internet:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Easier approach: modify<a href=\"https:\/\/www.terraform.io\/cli\/config\/config-file#cli-configuration-file-terraformrc-or-terraform-rc\"> terraform CLI configuration file<\/a><\/h4>\n\n\n\n<ul class=\"wp-block-list\"><li>For Windows: %APPDATA%\\terraform.rc file<\/li><li>For other systems: Home directory (linux ~) of the user running terraform, eg: ~\/.terraformrc<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Explicit tell terraform location of the downloaded provider binaries<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>provider_installation {\n  filesystem_mirror {\n    path    = \"<mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">\/mnt\/c\/gitrepos\/providers<\/mark>\"\n    include = &#91;\"AviatrixSystems\/aviatrix\"]\n  }\n}<\/code><\/pre>\n\n\n\n<p>Under filesystem_mirror section, you tell terraform where the downloaded binaries are, and which provider to use local downloaded binary. In above example, when terraform would use an Aviatrix provider, it will look under <mark style=\"background-color:#ffe2c7\" class=\"has-inline-color\">\/mnt\/c\/gitrepos\/providers<\/mark>. For any other providers, it will try to download from Internet.<\/p>\n\n\n\n<p>If you would run terraform init after this, it will goes very fast and wireshare will show zero packet left the instance while running terraform init.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- Finding aviatrixsystems\/aviatrix versions matching \"2.22.1\"...\n- Installing aviatrixsystems\/aviatrix v2.22.1...\n- Installed aviatrixsystems\/aviatrix v2.22.1 (unauthenticated)<\/code><\/pre>\n\n\n\n<p><a href=\"https:\/\/www.terraform.io\/cli\/config\/config-file#explicit-installation-method-configuration\">Read more <\/a>about this explicit configuration.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of our customers are looking to use Aviatrix to automatic their self-service process for AWS China region. The issue they are running into, was the terraform init would fail 50% of time. Is there anything we can do to &hellip; <a href=\"https:\/\/cloudlearning365.com\/?p=286\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2,8],"tags":[],"class_list":["post-286","post","type-post","status-publish","format-standard","hentry","category-aviatrix","category-terraform"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/posts\/286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=286"}],"version-history":[{"count":9,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions"}],"predecessor-version":[{"id":697,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions\/697"}],"wp:attachment":[{"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudlearning365.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}