Skip to content

Commit

Permalink
chore: Prefer other methods over $INSTANCE_ID (#5661)
Browse files Browse the repository at this point in the history
$INSTANCE_ID is an environment variable that contains a reference
to the current instance id. Its use is no longer needed now that
we can use jinja templates with {{ v1.instance_id }}. Furthermore,
`cloud-init-per` is a better replacement for running scripts once
per instance.

In particular, this commit does the following:
- Add jinja templating functionality to boothooks to be consistent
  with other core user data types
- Document cloud-id and cloud-init-per as they were previously
  undocumented
- Replace all $INSTANCE_ID references in docs to either use
  {{ v1.instance_id }} or the `cloud-init-per` script
- Update documentation of $INSTANCE_ID to now be deprecated
- Update tests as necessary
  • Loading branch information
TheRealFalcon committed Sep 9, 2024
1 parent 5d91e96 commit 7a0d957
Show file tree
Hide file tree
Showing 19 changed files with 120 additions and 80 deletions.
4 changes: 2 additions & 2 deletions cloudinit/config/cc_phone_home.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@

LOG = logging.getLogger(__name__)
# phone_home:
# url: http://my.foo.bar/$INSTANCE/
# url: http://my.foo.bar/{{ v1.instance_id }}/
# post: all
# tries: 10
#
# phone_home:
# url: http://my.foo.bar/$INSTANCE_ID/
# url: http://my.foo.bar/{{ v1.instance_id }}/
# post: [ pub_key_rsa, pub_key_ecdsa, instance_id, hostname,
# fqdn ]
#
Expand Down
10 changes: 8 additions & 2 deletions cloudinit/stages.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,15 +640,21 @@ def _default_handlers(self, opts=None) -> List[handlers.Handler]:
# TODO(harlowja) Hmmm, should we dynamically import these??
cloudconfig_handler = CloudConfigPartHandler(**opts)
shellscript_handler = ShellScriptPartHandler(**opts)
boothook_handler = BootHookPartHandler(**opts)
def_handlers = [
cloudconfig_handler,
shellscript_handler,
ShellScriptByFreqPartHandler(PER_ALWAYS, **opts),
ShellScriptByFreqPartHandler(PER_INSTANCE, **opts),
ShellScriptByFreqPartHandler(PER_ONCE, **opts),
BootHookPartHandler(**opts),
boothook_handler,
JinjaTemplatePartHandler(
**opts, sub_handlers=[cloudconfig_handler, shellscript_handler]
**opts,
sub_handlers=[
cloudconfig_handler,
shellscript_handler,
boothook_handler,
],
),
]
return def_handlers
Expand Down
1 change: 0 additions & 1 deletion doc/examples/cloud-config-boot-cmds.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# This is very similar to runcmd, but commands run very early
# in the boot process, only slightly after a 'boothook' would run.
# - bootcmd will run on every boot
# - INSTANCE_ID variable will be set to the current instance ID
# - 'cloud-init-per' command can be used to make bootcmd run exactly once
bootcmd:
- echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts
Expand Down
7 changes: 3 additions & 4 deletions doc/examples/cloud-config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ runcmd:
# This is very similar to runcmd above, but commands run very early
# in the boot process, only slightly after a 'boothook' would run.
# - bootcmd will run on every boot
# - INSTANCE_ID variable will be set to the current instance ID
# - 'cloud-init-per' command can be used to make bootcmd run exactly once
bootcmd:
- echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts
Expand Down Expand Up @@ -315,15 +314,15 @@ final_message: "The system is finally up, after $UPTIME seconds"

# phone_home: if this dictionary is present, then the phone_home
# cloud-config module will post specified data back to the given
# url
# url. Note that this example requires a `## template: jinja` header
# default: none
# phone_home:
# url: http://my.foo.bar/$INSTANCE/
# url: http://my.foo.bar/{{ v1.instance_id }}/
# post: all
# tries: 10
#
phone_home:
url: http://my.example.com/$INSTANCE_ID/
url: http://my.example.com/{{ v1.instance_id }}/
post: [ pub_key_rsa, pub_key_ecdsa, instance_id ]

# timezone: set the timezone for this instance
Expand Down
2 changes: 1 addition & 1 deletion doc/man/cloud-init-per.1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This can be one of the following values:
run only once and do not re-run for new instance-id

.BR "instance" ":"
run only the first boot for a given instance-id
run only once for a given instance-id and re-run for new instance-id

.BR "always" ":"
run every boot
Expand Down
7 changes: 5 additions & 2 deletions doc/module-docs/cc_bootcmd/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ cc_bootcmd:
description: |
This module runs arbitrary commands very early in the boot process, only
slightly after a boothook would run. This is very similar to a boothook,
but more user friendly. The environment variable ``INSTANCE_ID`` will be
set to the current instance ID for all run commands. Commands can be
but more user friendly. Commands can be
specified either as lists or strings. For invocation details, see
``runcmd``.
Expand All @@ -14,6 +13,10 @@ cc_bootcmd:
.. note::
When writing files, do not use ``/tmp`` dir as it races with
``systemd-tmpfiles-clean`` (LP: #1707222). Use ``/run/somedir`` instead.
.. warning::
Use of ``INSTANCE_ID`` variable within this module is deprecated.
Use :ref:`jinja templates<user_data_formats-jinja>` with
:ref:`v1.instance_id<v1_instance_id>` instead.
examples:
- comment: |
Example 1:
Expand Down
20 changes: 12 additions & 8 deletions doc/module-docs/cc_phone_home/data.yaml
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
cc_phone_home:
description: |
This module can be used to post data to a remote host after boot is
complete. If the post URL contains the string ``$INSTANCE_ID`` it will be
replaced with the ID of the current instance.
complete.
Either all data can be posted, or a list of keys to post.
Available keys are:
- ``pub_key_rsa``
- ``pub_key_ecdsa``
- ``pub_key_ed25519``
- ``instance_id``
- ``hostname``
- ``fdqn``
Data is sent as ``x-www-form-urlencoded`` arguments.
**Example HTTP POST**:
.. code-block:: http
POST / HTTP/1.1
Content-Length: 1337
User-Agent: Cloud-Init/21.4
Accept-Encoding: gzip, deflate
Accept: */*
Content-Type: application/x-www-form-urlencoded
pub_key_rsa=rsa_contents&pub_key_ecdsa=ecdsa_contents&pub_key_ed25519=ed25519_contents&instance_id=i-87018aed&hostname=myhost&fqdn=myhost.internal
.. warning::
Use of ``INSTANCE_ID`` variable within this module is deprecated.
Use :ref:`jinja templates<user_data_formats-jinja>` with
:ref:`v1.instance_id<v1_instance_id>` instead.
examples:
- comment: |
Example 1:
Expand Down
3 changes: 2 additions & 1 deletion doc/module-docs/cc_phone_home/example1.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
## template: jinja
#cloud-config
phone_home: {post: all, url: 'http://example.com/$INSTANCE_ID/'}
phone_home: {post: all, url: 'http://example.com/{{ v1.instance_id }}/'}
3 changes: 2 additions & 1 deletion doc/module-docs/cc_phone_home/example2.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## template: jinja
#cloud-config
phone_home:
post: [pub_key_rsa, pub_key_ecdsa, pub_key_ed25519, instance_id, hostname, fqdn]
tries: 5
url: http://example.com/$INSTANCE_ID/
url: http://example.com/{{ v1.instance_id }}/
34 changes: 19 additions & 15 deletions doc/rtd/explanation/format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ Explanation
A user data script is a single script to be executed once per instance.
User data scripts are run relatively late in the boot process, during
cloud-init's :ref:`final stage<boot-Final>` as part of the
:ref:`cc_scripts_user<mod_cc_scripts_user>` module. When run,
the environment variable ``INSTANCE_ID`` is set to the current instance ID
for use within the script.
:ref:`cc_scripts_user<mod_cc_scripts_user>` module.

.. warning::
Use of ``INSTANCE_ID`` variable within user data scripts is deprecated.
Use :ref:`jinja templates<user_data_formats-jinja>` with
:ref:`v1.instance_id<v1_instance_id>` instead.

.. _user_data_formats-cloud_boothook:

Expand All @@ -114,16 +117,10 @@ Example of once-per-instance script
#cloud-boothook
#!/bin/sh
PERSIST_ID=/var/lib/cloud/first-instance-id
_id=""
if [ -r $PERSIST_ID ]; then
_id=$(cat /var/lib/cloud/first-instance-id)
fi
if [ -z $_id ] || [ $INSTANCE_ID != $_id ]; then
echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts
fi
sudo echo $INSTANCE_ID > $PERSIST_ID
# Early exit 0 when script has already run for this instance-id,
# continue if new instance boot.
cloud-init-per instance do-hosts /bin/false && exit 0
echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts
Explanation
-----------
Expand All @@ -139,6 +136,11 @@ The boothook is different in that:
before any cloud-init modules are run.
* It is run on every boot

.. warning::
Use of ``INSTANCE_ID`` variable within boothooks is deprecated.
Use :ref:`jinja templates<user_data_formats-jinja>` with
:ref:`v1.instance_id<v1_instance_id>` instead.

Include file
============

Expand All @@ -159,6 +161,8 @@ be read and their content can be any kind of user data format, both base
config and meta config. If an error occurs reading a file the remaining files
will not be read.

.. _user_data_formats-jinja:

Jinja template
==============

Expand Down Expand Up @@ -191,8 +195,8 @@ as jinja template variables. Any jinja templated configuration must contain
the original header along with the new jinja header above it.

.. note::
Use of Jinja templates is ONLY supported for cloud-config and user data
scripts. Jinja templates are not supported for cloud-boothooks or
Use of Jinja templates is supported for cloud-config, user data
scripts, and cloud-boothooks. Jinja templates are not supported for
meta configs.

.. _user_data_formats-mime_archive:
Expand Down
2 changes: 2 additions & 0 deletions doc/rtd/explanation/instancedata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ Example output:
- sles, 12.3, x86_64
- ubuntu, 20.04, focal

.. _v1_instance_id:

``v1.instance_id``
^^^^^^^^^^^^^^^^^^

Expand Down
3 changes: 2 additions & 1 deletion doc/rtd/howto/module_run_frequency.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ Then your user data could then be:

.. code-block:: yaml
## template: jinja
#cloud-config
phone_home:
url: http://example.com/$INSTANCE_ID/
url: http://example.com/{{ v1.instance_id }}/
post: all
Loading

0 comments on commit 7a0d957

Please sign in to comment.