Saturday, July 6, 2013

Deploy to Windows Azure using git with private submodules

Overview

Windows Azure supports continuous deployment from GitHubBitbucket and CodePlex.  This includes both public and private repositories.   For private repository, Windows Azure generates an SSH key pair.  The public SSH part is added to the repository's deployment key while the private one is used to fetch the repository content during deployment.  If the repository contains submodules, their contents will also be fetched automatically.

It becomes interesting when submodules happen to be private repositories.   Since Windows Azure, by default, uses the same SSH private key to fetch the main repository as well as its submodules, one can workaround by manually propagating the SSH deployment key across all related submodules.  Note that you have to make sure all submodules are fetched using SSH (not https) by looking at .gitmodules file (see url property).  This works well with Bitbucket but fails in GitHub.   The reason is GitHub uses SSH key as an identifier; hence, it can only be defined once for either a user key or repository deployment key across GitHub site.

Below describes a few workarounds for the GitHub issue.

Dedicated user with pull permission

This is the simplest workaround by introducing a new dedicated user with pull permission to all related private repositories (main and submodules) required for deploying to Windows Azure and set an appropriate SSH key pair to this user and Windows Azure.  There are two ways to achieve this depending on whether your main repository is public or private.

If the main repository is private, the private SSH key is already set to Windows Azure and you will only need to deal with public key part.  Simply copy the deployment key (d:\home\.ssh\id_rsa.pub) from your webapp (using FTP or Kudu Console) and paste to this user as user SSH key.  Because GitHub only allows one unique key, you may have to delete the deployment key from repo before add as a user key.

If the main repository is public, Windows Azure will not generate nor set any SSH key pair.   In this case, you will have to generate the key pair manually (ssh-keygen).  The public part (id_rsa.pub) should be set as user key of the dedicated user above.  Upload the private key (id_rsa) part to Windows Azure (you may follow Giving the private key to the Kudu service instruction).

This is simplest and recommended way.


Use different SSH keys for each repositories

This solution is to take advantage of SSH alias support in SSH configuration.  This allows us to speficy different private key files (id_rsa) to be used to access different repositories.

Let's assume, we are dealing with 2 private submodules (say repo1 and repo2).  First, generate two set of key pairs (one for each repositories) and add the public part as deployment key for appropriate repositories.

Configure the ssh configuration file (~/.ssh/config) to use different private key files for different repositories as follow.

Host github-repo1
    User git
    HostName github.com
    IdentityFile ~/.ssh/id_isa.repo1
    StrictHostKeyChecking no

Host github-repo2
    User git
    HostName github.com
    IdentityFile ~/.ssh/id_isa.repo1
    StrictHostKeyChecking no

You can test if it is properly configured by doing a git clone/pull from each repositories.

$ git clone git@github-repo1:account/repo1.git
$ git clone git@github-repo2:account/repo2.git

Use FTP to upload ~/.ssh/config, ~/.ssh/id_rsa.repo1 and ~/.ssh/id_rsa.repo2 to Windows Azure's /site/.ssh folder.    Modify and commit the .gitmodules file along with you rmain repository.

[submodule "repo1"]
  path = repo1path
  url = git@github-repo1:account/repo1.git

[submodule "repo2"]
  path = repo2path
  url = git@github-repo1:account/repo2.git

Windows Azure should be able to fetch the main and its submodules successfully.   By the way, this solution only works well if you are the only one using these repositories and your have propagated the ssh's configuration as well as id_rsa key files to all your git client machines.

Hope it helps.
  

12 comments:

  1. Sorry, I think i'm missing some steps/details here.

    1. I created a new user and added it to a team in my org that has pull permissions on all relevant repos.
    2. I disconnected from GH and tried to reconnect using this user.

    It just tells me I have no repos for this user.

    ReplyDelete
  2. In order to link Github repo to Website, the user must have admin permission to the repo. The reason is that we will need to set webhook and, in private repo case, SSH deploy key. After that, one only needs Pull permission.

    ReplyDelete
    Replies
    1. Thanks. The other catch is to ensure that your submodules (in .gitmodules) are setup using SSH and not HTTPS. If you do that + the other steps above, at least I was able to get it pulling submodules correctly.

      Delete
    2. One other thing, if you try to deploy before the submodules are setup, you will need to fix your .git/config file--remove the submodule entries and then init again. (You may also need to delete your module directories just to be on the safe side.)

      Delete
  3. Are the submodules automatically updated on every pull of the main repository? If not how can we do that?

    ReplyDelete
  4. I have a similar situation: Github, private module and private submodule. I was able to autodeploy after generating ssh keys for the submodule repo and copying them the private and config file to .ssh folder of Azure site , while adding the public one to the account in Github used for deployment.
    The problem is that every time I disable the auto deployment, the files are gone, and I have to copy them again to Azure next time, pretty fast, before the auto deployment reaches the point where it fetches the submodule and needs them.
    We use this as a deployment method for production, so every 2 weeks I need to do this dance, once for each of our sites. I wish there is a way to configure the ssh keys for the machine so they are not gone when the auto deployment is disabled.

    ReplyDelete
  5. nice information well done your information is helping alot thanks for valuable windows azure training in hyderabad

    ReplyDelete
  6. I am not finished however; I have a lot more to impart to you. Things your Palm Beach PC repair tech won't reveal to you lessons three and four will be posted in the blink of an eye. https://how-to-remove.org/malware/browser-hijacker-removal/picasti-extension-removal/

    ReplyDelete
  7. best windows azure online training in hyderabad with work support and job assistance and high quality training facilities and well expert faculty
    to Register you free demo please visit
    windows azure training in hyderabad

    ReplyDelete
  8. If anyone want to become an Devops certified professional reach Besant Technologies, which offers best Devops Training in Bangalore with years of experienced professionals. For more details about courses… Software Testing Training in Bangalore

    ReplyDelete
  9. I have added new sub module to my existing web app and also added the public and private ssh keys to .ssh folder on azure. My config file is like this..

    Host repo
    User stekule2011
    HostName bitbucket.org
    IdentityFile ~/.ssh/id_rsa2
    StrictHostKeyChecking no

    but still I am getting an error that ...
    "Cloning into 'repo'...\nrepository access denied. deployment key is not associated with the requested repository.\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\nfatal: clone of 'git@bitbucket.org:stekule2011/repo.git' into submodule path 'repo' failed\n\r\nD:\Program Files (x86)\Git\cmd\git.exe submodule update --init --recursive --force"

    I have added the public key to my bit bucket repo as access key.
    any suggestions ??

    ReplyDelete
  10. Nice Blog on Deploy to Windows Azure using git with private submodules. Thank you for Such a Great Blog.
    Devops Training in Bangalore

    ReplyDelete