Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question about cloud-init #588

Closed
MattPumphrey opened this issue Aug 14, 2018 · 7 comments
Closed

question about cloud-init #588

MattPumphrey opened this issue Aug 14, 2018 · 7 comments

Comments

@MattPumphrey
Copy link

So, I have been working through a problem, and I have been trying to use cloud-init to bootstrap my vms, while, I can see on the VMs that the cloud-init userdata is being passed into the vmtoolsd guestinfo namespace when I use the extra_config options

 extra_config {
   "guestinfo.cloudinit.userdata" = "${data.template_cloudinit_config.cloud-init-config.rendered}"
 } 

here is my template

data "template_cloudinit_config" "cloud-init-config" {
  gzip          = true
  base64_encode = true

  # lay down rendered userdata script
  part {
    content_type = "text/cloud-config"

    content = <<EOF
write_files:
  - content: |
      ${base64encode(data.template_file.userdata.rendered)}
    encoding: b64
    owner: root:root
    path: /usr/local/bin/userdata.sh
    permissions: '0700'
  - content: |
      ${base64encode(data.template_file.client-rb.rendered)}
    encoding: b64
    owner: root:root
    path: /etc/chef/client.rb
    permissions: '0644'
  - content: |
      ${base64encode(data.template_file.autoscaling-janitor.rendered)}
    encoding: b64
    owner: root:root
    path: /etc/init.d/autoscaling-janitor
    permissions: '0755'
  - content: |
      { "run_list": [${var.chef-run-list}] }
    owner: root:root
    path: /etc/chef/first-boot.json
    permissions: '0644'
runcmd:
 - [ /usr/local/bin/userdata.sh ]
packages:
  - python3
EOF
  }
}

The files do not actually get written to the file system, I have tried creating the userdata.txt and mounting it as an ISO from the datastore and that fails as well. Do I need to have the CDrom added as a client device and then use the extra_config options for this to work? If someone has been successful on doing this and can point me in the right direction that would be much appreciated. To give a little background, we are building our images via Packer, and soon to be Ansible and packer for a base build with Chef doing the final provisioning.

I have even tried to use this, https://github.com/xing/cloudinit-vmware-guestinfo but it also fails for me. Any help would be appreciated.

@MnrGreg
Copy link

MnrGreg commented Sep 24, 2018

@MattPumphrey Here is a official VMware version for implementing: https://github.com/akutz/cloud-init-vmware-guestinfo

I haven't tested with Terraforms extra_config as yet but looks like it should work well. Doesn't require OVF template or vApp.

Thanks to @akutz

@akutz
Copy link

akutz commented Sep 24, 2018

No problem! Glad someone’s using it. If you check out https://github.com/akutz/yake2e, you’ll see it in use with TF and extra config :)

@akutz
Copy link

akutz commented Sep 24, 2018

Here’s a line where it’s injected -
https://github.com/akutz/yake2e/blob/master/vsphere.tf#L102. Check out cloud_config.tf to see where it is built. FYI, there is an undocumented size limit to the guestinfo interface as I learned myself recently (I’m still new to VMware). It just starts truncating a little before 100KiB. Make sure you gzip AND base64 encode. The pain is, if cloud config supported URL encoded values, the size could get real small. Gzip’ing inner content and then gzip’ing it again via the cloud config greatly impacts overall compression. I ran some tests, hang on.

@akutz
Copy link

akutz commented Sep 24, 2018

Found it. Just going to paste in a Slack chat:

By the way, after some tests here are the results:

-rw-r--r--@  1 akutz  staff    94K Aug 28 11:39 cc.base64.base64
-rw-r--r--@  1 akutz  staff    32K Aug 28 11:40 cc.base64.gzip
-rw-r--r--@  1 akutz  staff    51K Aug 28 11:38 cc.gzip.base64
-rw-r--r--@  1 akutz  staff    31K Aug 28 11:41 cc.gzip.gzip
-rw-r--r--@  1 akutz  staff    22K Aug 28 11:49 cc.plaintext.gzip
-rw-r--r--@  1 akutz  staff    23K Aug 28 11:49 cc.urlencode.gzip

Each file is cloud config data. The first extension indicates how the child documents are encoded. The second extension indicates how the outer document is encoded. As you can see from comparing cc.gzip.gzip and cc.base64.gzip, there is a very minor improvement if child content is compressed prior to being included in the outer content. But it's very minor.

Now, cc.plaintext.gzip is of course the most compressed. Unfortunately it represents the inner-content as plain-text. This is not possible in production thanks to the outer content's rules about valid characters.

However, it occurred to me to consider using URL encoding for the inner content instead of base64 encoding. The URL encoding should make the characters safe for YAML-transport, and look at the results! Only fractionally worse than the inner-content as plain-text.

And yet, unfortunately once more, cloud config doesn't support URL encoding for its file content (https://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing-out-arbitrary-files):

encoding can be given b64 or gzip or (gz+b64).

In the end it looks like gzip+gzip is the best solution for the situational constraints. Without those restrictions in the way, keeping the inner content as plain-text offers the best compression.

@bill-rich
Copy link
Contributor

Thanks @MnrGreg & @akutz. Thats some real interesting info on cloud init.

@MattPumphrey Does using https://github.com/akutz/cloud-init-vmware-guestinfo resolve your problem for you?

@MattPumphrey
Copy link
Author

This is alot of really interesting information, I have yet to test this out, however you can close this as it has given me a lot more information than I previously had on how to successfully get my VMs deployed in this manner! Thanks @MnrGreg & @akutz

@bill-rich thanks for all your help!

@SerenaLi279
Copy link

Hello,
May I ask a question?
For the extra_config https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html#extra_config
How to use cloud-init with terraform, if I use template imported from OVF?

@ghost ghost locked and limited conversation to collaborators Apr 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants