title: How to source Terraform module hosted within Azure DevOps Repo via ssh
body: <p>Looking for the correct/working way to source a Terraform module that is hosted within a private Azure DevOps git repo via SSH (see <a href="https://www.terraform.io/docs/language/modules/sources.html#generic-git-repository" rel="nofollow noreferrer">TF Docs on Git repo sourcing via ssh</a>).</p>
  <p>It's undesirable to have a PAT token as it will eventually expire and renewal can't be automated yet (<a href="https://devblogs.microsoft.com/devops/new-personal-access-token-lifecycle-apis-in-private-preview/" rel="nofollow noreferrer">although coming soon apparently</a>). Despite that, have validated the https method but I would like to avoid needing to edit the source if I can as module source references <a href="https://www.terraform.io/docs/language/modules/syntax.html#source" rel="nofollow noreferrer">can't include terraform vars at init time</a>.</p>
  <p>I have followed the following <a href="https://docs.microsoft.com/en-us/azure/devops/repos/git/use-ssh-keys-to-authenticate?view=azure-devops#step-1-create-your-ssh-keys" rel="nofollow noreferrer">steps</a> to generate an ssh private/public key pair and those files have been added to my local <code>.ssh</code> folder @ <code>C:\Windows\Users\&lt;username&gt;\.ssh</code>.</p>
  <p>Example terraform code below:</p>
  <pre><code>module &quot;test&quot; {
      source = &quot;&lt;ref&gt;&quot;
  }
  </code></pre>
  <p>Where <code>&lt;ref&gt;</code> has been tested with:</p>
  <ul>
  <li><code>git::https://&lt;pat token&gt;:dev.azure.com/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt;//&lt;sub path&gt;?ref=&lt;version ref&gt;</code> - worked/validated https approach as last resort</li>
  <li><code>git::ssh://git@ssh.dev.azure.com:v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt;//&lt;sub path&gt;?ref=&lt;version ref&gt;</code></li>
  <li><code>git::ssh://git@ssh.dev.azure.com/v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt;//&lt;sub path&gt;?ref=&lt;version ref&gt;</code> - <a href="https://github.com/hashicorp/terraform/issues/18869" rel="nofollow noreferrer">see terraform/issues/18869</a></li>
  </ul>
  <p>After reading about <a href="https://docs.microsoft.com/en-us/azure/devops/repos/git/use-ssh-keys-to-authenticate?view=azure-devops#q-i-have-multiple-ssh-keys--how-do-i-use-different-ssh-keys-for-different-ssh-servers-or-repos" rel="nofollow noreferrer">multiple keys</a> here:</p>
  <blockquote>
  <p>Generally, if you configure multiple keys for an SSH client and connect to an SSH server, the client can try the keys one at a time until the server accepts one. However, this doesn't work with Azure DevOps for technical reasons related to the SSH protocol and how our Git SSH URLs are structured. Azure DevOps will blindly accept the first key that the client provides during authentication. If that key is invalid for the requested repo, the request will fail with the following error: remote: Public key authentication failed.
  fatal: Could not read from remote repository.</p>
  </blockquote>
  <p>I played around with my <code>.ssh/config</code> file including</p>
  <ul>
  <li>Removing all other keys other than the <code>automation</code> ssh key pair that I wanted to use specifically for this case (as opposed to my own personal SSH key identifying me)</li>
  <li>Updating <code>.ssh/config</code> to look like:</li>
  </ul>
  <pre><code>Host automation
      HostName ssh.dev.azure.com
      IdentityFile ~/.ssh/automation_account
      IdentitiesOnly yes
  Host azuredevops
      HostName ssh.dev.azure.com
      IdentityFile ~/.ssh/azuredevops
      IdentitiesOnly yes
  </code></pre>
  <p>And then within the <code>&lt;ref&gt;</code> trying:</p>
  <ul>
  <li><code>git::ssh://git@automation/v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt;//&lt;sub path&gt;?ref=&lt;version ref&gt;</code></li>
  <li><code>git::ssh://automation/v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt;//&lt;sub path&gt;?ref=&lt;version ref&gt;</code></li>
  </ul>
  <p>Where all of these attempts result in:</p>
  <pre><code>Permission denied, please try again.
  git@ssh.dev.azure.com: Permission denied (password,publickey).
  fatal: Could not read from remote repository.
  </code></pre>
  <p>Or</p>
  <pre><code>does not appear to be a git repository
  fatal: Could not read from remote repository.
  </code></pre>
  <p>The ssh key that I am using, have validated that it is registered with Azure DevOps by getting the thumbprint <code>ssh-keygen -E md5 -lf &lt;path to private key&gt;</code> and getting back <code>2048 MD5:ab:e2:... automation (RSA)</code> which I can confirm exists within Azure DevOps under my SSH keys.</p>
  <p>I have validated that the key allows me to access one of my target TF repos by adding a new git remote using that specific key. <code>git remote -v</code> gives me:</p>
  <pre><code>aorigin       git@automation:v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt; (fetch)
  aorigin       git@automation:v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt; (push)
  origin  git@ssh.dev.azure.com:v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt; (fetch)
  origin  git@ssh.dev.azure.com:v3/&lt;org name&gt;/&lt;project name&gt;/_git/&lt;repo name&gt; (push)
  </code></pre>
  <p>And a <code>git pull aorigin</code> works as expected. Origin is the original SSH clone url from the Azure DevOps gui.</p>
  <p>Almost certain that I am missing something obvious but after extensive Googling and a number of different configurations, cannot for the life of me get it to work. Help/pointers/suggestions appreciated</p>
  <p>Versions of tools:</p>
  <ul>
  <li>Terraform v0.13.4</li>
  <li>git version 2.17.1.windows.2</li>
  <li>OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5</li>
  </ul>