Git clone within user_data

Using user_data while launching an instance; running into an issue while cloning a git repo within the user_data block; was previously doing it via remote-exec, and that worked fine, but trying to move away from remote-exec. Here’s the code snippet

resource "openstack_compute_instance_v2" "ohpc" {
  name            = var.instance_name
  image_name      = var.image_name
  flavor_name     = var.flavor
  key_pair        = var.key_pair
  security_groups = ["default"]
  user_data = <<-EOF
     write_files:
     - content: |
       git clone path_to_git_repo dest
       path: /
       permissions: '0755'
    EOF

What sort of issue(s) are you having? Can I ask why you’ve decided to move away from remote-exec? Is it just to get away from using provisioners in general? Have you considered including the repository as part of an image building process instead?

  1. moving away from remote exec as hashicorp documentation itself mentions to use remote-exec as last resort Provisioner: remote-exec | Terraform | HashiCorp Developer
  2. I have considered to do it in the build itself, but that makes the build image quite large; also the repo does not need to exist in the instance (hence the remote exec worked fine, i would remotely run the ansible roles on the instance via my runner). This test (of cloning repo to the instance) is because i do not see any other option in user_data to do so.

Can I ask again: what sort of issue(s) are you having with this code snippet? I haven’t worked with cloud-init much, so please do take this with a grain of salt, but are you sure write-files is the directive you want to use there?

Looking at some examples, wouldn’t runcmd be more appropriate? (runcmd example) Also, to me, it looks like you aren’t naming the file to write (unless there’s a default value that it would append to your root path). (write_files example)

Hi @krishmoodbidri,

This is more a cloud-init question than a Terraform question, so I’m going to try my best to help but I must first admit that I’m not a big cloud-init expert and so I might not get everything right.

I think the relevant documentation here is:

Based on that information, the configuration you’ve shared seems to be specifying to create a file called / which has the content git clone path_to_git_repo dest. First this seems incorrect because / is the path to a directory, not a filename. But even if this was a filename, all this would achieve is to create a file containing a shell command to run git, and would not actually cause that command to be run.

cloud-init does not seem to have a module specifically for cloning git repositories, so I think you will need to solve this using a pattern like what’s shown in Run commands on first boot, which I notice is what @jlj7 also suggested.

It seems like you will need to decide between bootcmd and runcmd based on when during the boot process the action needs to be taken. I am not sure when exactly each of those modules run, but since this git clone command will need to make a request over the network I think bootcmd might be too early, and so you might need to use runcmd:

runcmd:
  - |
    mkdir /run/example
    git clone path_to_git_repo /run/example/dest

Assuming that I’m understanding the documentation example correctly, I would expect this to:

  1. Create a temporary file containing the two commands as a shell script.
  2. Run that file using the default shell.

There are some other details I’ve not dealt with here that might be important:

If this doesn’t do what you’re expecting then you may find it useful to refer to How to debug cloud-init for guidance on how to understand how cloud-init understood the cloud-config structure and what happened when it took the actions described in there.

1 Like