From a816255d95486a95704b4008b376232340f75b75 Mon Sep 17 00:00:00 2001 From: Michele Cereda Date: Tue, 23 Apr 2024 00:00:14 +0200 Subject: [PATCH] chore(examples/pulumi): add example for multi-part cloud-init --- examples/cloud-init/aws.ssm.yaml | 14 ++++ examples/pulumi/multi-part cloud-init/.env | 1 + .../pulumi/multi-part cloud-init/.gitignore | 3 + .../multi-part cloud-init/Pulumi.all.yaml | 7 ++ .../pulumi/multi-part cloud-init/Pulumi.yaml | 9 +++ .../pulumi/multi-part cloud-init/index.ts | 23 ++++++ .../pulumi/multi-part cloud-init/package.json | 11 +++ .../multi-part cloud-init/tsconfig.json | 18 +++++ knowledge base/cloud-init.md | 78 ++++++++++++++----- 9 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 examples/cloud-init/aws.ssm.yaml create mode 100644 examples/pulumi/multi-part cloud-init/.env create mode 100644 examples/pulumi/multi-part cloud-init/.gitignore create mode 100644 examples/pulumi/multi-part cloud-init/Pulumi.all.yaml create mode 100644 examples/pulumi/multi-part cloud-init/Pulumi.yaml create mode 100644 examples/pulumi/multi-part cloud-init/index.ts create mode 100644 examples/pulumi/multi-part cloud-init/package.json create mode 100644 examples/pulumi/multi-part cloud-init/tsconfig.json diff --git a/examples/cloud-init/aws.ssm.yaml b/examples/cloud-init/aws.ssm.yaml new file mode 100644 index 0000000..66c7163 --- /dev/null +++ b/examples/cloud-init/aws.ssm.yaml @@ -0,0 +1,14 @@ +#cloud-config + +# Install and enable the SSM agent on supported instances. + +# Tested on: +# - Amazon Linux 2023.4.20240416 + +package_upgrade: false +packages: + - amazon-ssm-agent + +runcmd: + - systemctl daemon-reload + - systemctl enable --now 'amazon-ssm-agent.service' diff --git a/examples/pulumi/multi-part cloud-init/.env b/examples/pulumi/multi-part cloud-init/.env new file mode 100644 index 0000000..41d3df1 --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/.env @@ -0,0 +1 @@ +PULUMI_CONFIG_PASSPHRASE=test123 diff --git a/examples/pulumi/multi-part cloud-init/.gitignore b/examples/pulumi/multi-part cloud-init/.gitignore new file mode 100644 index 0000000..37a8612 --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/node_modules/ +/package-lock.json diff --git a/examples/pulumi/multi-part cloud-init/Pulumi.all.yaml b/examples/pulumi/multi-part cloud-init/Pulumi.all.yaml new file mode 100644 index 0000000..ba72914 --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/Pulumi.all.yaml @@ -0,0 +1,7 @@ +encryptionsalt: v1:Tl2L4ymfbTk=:v1:PNPJ5bUKKgCFe8G/:hrgipeFmFMPSAYcf5lgS6dUCe33WtA== +config: + aws:defaultTags: + tags: + ManagedBy: pulumi + PulumiProject: cloud-init.multi-part + aws:region: eu-west-1 diff --git a/examples/pulumi/multi-part cloud-init/Pulumi.yaml b/examples/pulumi/multi-part cloud-init/Pulumi.yaml new file mode 100644 index 0000000..ba3a68f --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/Pulumi.yaml @@ -0,0 +1,9 @@ +name: cloud-init.multi-part +runtime: nodejs +description: Simple example of multi-part cloud-init usage +config: + pulumi:tags: + value: + pulumi:template: typescript +backend: + url: file://. diff --git a/examples/pulumi/multi-part cloud-init/index.ts b/examples/pulumi/multi-part cloud-init/index.ts new file mode 100644 index 0000000..67099c4 --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/index.ts @@ -0,0 +1,23 @@ +import * as cloudinit from "@pulumi/cloudinit"; +import * as fs from 'fs'; + +export const userData = new cloudinit.Config( + "userData", + { + gzip: false, + base64Encode: false, + parts: [ + { + contentType: "text/cloud-config", + content: fs.readFileSync("../../cloud-init/aws.ssm.yaml", "utf8"), + filename: "cloud-config.ssm.yml", + }, + { + contentType: "text/cloud-config", + content: fs.readFileSync("../../cloud-init/docker.yum.yaml", "utf8"), + filename: "cloud-config.docker.yml", + mergeType: "dict(recurse_array,no_replace)+list(append)", + }, + ], + }, +); diff --git a/examples/pulumi/multi-part cloud-init/package.json b/examples/pulumi/multi-part cloud-init/package.json new file mode 100644 index 0000000..ff86adb --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/package.json @@ -0,0 +1,11 @@ +{ + "name": "cloud-init.multi-part", + "main": "index.ts", + "devDependencies": { + "@types/node": "^18" + }, + "dependencies": { + "@pulumi/cloudinit": "^1.4.1", + "typescript": "^5.0.0" + } +} \ No newline at end of file diff --git a/examples/pulumi/multi-part cloud-init/tsconfig.json b/examples/pulumi/multi-part cloud-init/tsconfig.json new file mode 100644 index 0000000..f960d51 --- /dev/null +++ b/examples/pulumi/multi-part cloud-init/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "strict": true, + "outDir": "bin", + "target": "es2020", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "experimentalDecorators": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.ts" + ] +} diff --git a/knowledge base/cloud-init.md b/knowledge base/cloud-init.md index 570644f..377d62e 100644 --- a/knowledge base/cloud-init.md +++ b/knowledge base/cloud-init.md @@ -4,9 +4,8 @@ 1. [TL;DR](#tldr) 1. [Merge 2 or more files or parts](#merge-2-or-more-files-or-parts) - 1. [In Terraform](#in-terraform) 1. [Further readings](#further-readings) -1. [Sources](#sources) + 1. [Sources](#sources) ## TL;DR @@ -76,8 +75,6 @@ runcmd: ## Merge 2 or more files or parts -FIXME - See [Merging User-Data sections] for details. ```yaml @@ -103,9 +100,50 @@ packages: merge_type: 'list(append)+dict(recurse_array)+str()' ``` -### In Terraform +
+ In Pulumi -1. create a data resource containing the files in order, one per part: +1. Create a data resource containing the files in order, one per part: + + ```ts + new cloudinit.Config("example", { + gzip: false, + base64Encode: false, + parts: [ + { + contentType: "text/cloud-config", + content: fs.readFileSync("cloud-init/aws.ssm.yaml", "utf8"), + filename: "cloud-config.ssm.yml", + }, + { + contentType: "text/cloud-config", + content: YAML.stringify({ + number: 3, + plain: 'string', + block: 'two\nlines\n' + }), + filename: "cloud-config.inline.yml", + mergeType: "dict(recurse_array,no_replace)+list(append)", + }, + ], + }); + ``` + +1. Give its rendered form as input to a virtual machine's `userdata` attribute, or export it: + + ```ts + let userData = new cloudinit.Config("userData", { … }); + new aws.ec2.Instance("instance", { + userData: userData.rendered, + … + }) + ``` + +
+
+ In Terraform + +1. Create a data resource containing the files in order, one per part: ```hcl # https://registry.terraform.io/providers/hashicorp/cloudinit/latest/docs @@ -134,7 +172,7 @@ merge_type: 'list(append)+dict(recurse_array)+str()' } ``` -1. give its rendered form as input to a vm's userdata attribute or an output resource: +1. Give its rendered form as input to a virtual machine's `userdata` attribute or an output resource: ```hcl resource "azurerm_linux_virtual_machine" "vm" { @@ -147,6 +185,8 @@ merge_type: 'list(append)+dict(recurse_array)+str()' } ``` +
+ ## Further readings - [Website] @@ -158,9 +198,7 @@ merge_type: 'list(append)+dict(recurse_array)+str()' - [Mime Multi Part Archive] format - [Docker cloud init example] -## Sources - -All the references in the [further readings] section, plus the following: +### Sources - [Debugging cloud-init] - [Tutorial] @@ -172,21 +210,19 @@ All the references in the [further readings] section, plus the following: References --> - -[debugging cloud-init]: https://canonical-cloud-init.readthedocs-hosted.com/en/latest/howto/debugging.html -[examples]: https://cloudinit.readthedocs.io/en/latest/topics/examples.html -[merging user-data sections]: https://canonical-cloud-init.readthedocs-hosted.com/en/latest/reference/merging.html -[modules]: https://cloudinit.readthedocs.io/en/latest/topics/modules.html -[mime multi part archive]: https://cloudinit.readthedocs.io/en/latest/topics/format.html#mime-multi-part-archive -[tutorial]: https://canonical-cloud-init.readthedocs-hosted.com/en/latest/tutorial/ -[website]: https://cloud-init.io/ - -[further readings]: #further-readings - [docker cloud init example]: ../examples/cloud-init/docker.yum.yaml + +[debugging cloud-init]: https://docs.cloud-init.io/en/latest/howto/debugging.html +[examples]: https://docs.cloud-init.io/en/latest/reference/examples.html +[merging user-data sections]: https://docs.cloud-init.io/en/latest/reference/merging.html +[modules]: https://cloudinit.readthedocs.io/en/latest/topics/modules.html +[mime multi part archive]: https://cloudinit.readthedocs.io/en/latest/topics/format.html#mime-multi-part-archive +[tutorial]: https://docs.cloud-init.io/en/latest/tutorial/ +[website]: https://cloud-init.io/ + [cloud-init configuration merging]: https://jen20.dev/post/cloudinit-configuration-merging/ [cloud-init multipart encoding issues]: https://github.com/hashicorp/terraform/issues/4794