-
Notifications
You must be signed in to change notification settings - Fork 881
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add yaml example that does math and uses pulumi-std functions
- Loading branch information
1 parent
549de02
commit c34d467
Showing
2 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
name: yaml-math-and-objects | ||
description: A Pulumi YAML program that demonstrates how to do math and manipulate objects in YAML. | ||
runtime: yaml | ||
|
||
## Stack Config | ||
config: | ||
# The length of the string to generate. | ||
length: | ||
type: integer | ||
default: 16 | ||
# When this config is set to true, we then want to implement some logic related to the string generation. | ||
useLowerCase: | ||
type: boolean | ||
default: true | ||
# An array of key-value pairs as strings used to build the keepers map array. | ||
configKeepersArray: | ||
type: array | ||
items: | ||
type: string | ||
default: | ||
- "configKey1:configValue1" | ||
- "configKey2:configValue2" | ||
|
||
|
||
## Variables used by the RandomString resource below constructed from the config and functions and a little help from the Command resource. | ||
variables: | ||
# Get the length from the config. | ||
stringLength: ${length} | ||
|
||
# Build keepersArrayPart1 using the structured config (which is limited to an array of strings) by leveraging pulumi-std functions | ||
# to build the requisite map array. | ||
keepersArrayPart1: | ||
# Build the required map array from an array of strings such that each pair of strings is used to create the key-value pair. | ||
fn::invoke: | ||
function: std:map | ||
arguments: | ||
args: | ||
# Split the string of strings created by joining the array of strings from the config. | ||
# This is needed for the map function to build the array of key-value pairs. | ||
fn::invoke: | ||
function: std:split | ||
arguments: | ||
separator: ":" | ||
text: | ||
# Build one big string of strings from the array of strings in the config. | ||
fn::invoke: | ||
function: std:join | ||
arguments: | ||
# The array of strings from the config. | ||
input: ${configKeepersArray} | ||
separator: ":" | ||
return: result | ||
return: result | ||
return: result | ||
|
||
# Hard-coded map for the second part of the keepers array to have something to merge. | ||
keepersArrayPart2: | ||
part2aKey: "part2aValue" | ||
part2bKey: "part2bValue" | ||
|
||
# Combine the two parts of the keepers map arrays into a single map array to be used in the RandomString resource. | ||
keepersArrayCombined: | ||
fn::invoke: | ||
function: std:merge | ||
arguments: | ||
input: | ||
- ${keepersArrayPart1} | ||
- ${keepersArrayPart2} | ||
return: result | ||
|
||
# Lowercase settings object to use for the RandomString resource. | ||
lowerCaseSettings: | ||
# Just passing along the config value as part of this variable. | ||
uselower: ${useLowerCase} | ||
# Want to only set minLower based on length and only set it if useLowerCase is true. | ||
# Since we don't have a way to run logic and math in YAML, we can use the Pulumi Command resource (see below) to do this. | ||
# But we need to use the srd-pareint function to convert the string output from the Command resource to an integer for the RandomString resource. | ||
minLower: | ||
fn::invoke: | ||
function: std:parseint | ||
arguments: | ||
input: ${calculateMinLower.stdout} | ||
return: result | ||
|
||
## Resources | ||
resources: | ||
# Creating a RandomString resource (https://www.pulumi.com/registry/packages/random/api-docs/randomstring/) | ||
randomString: | ||
type: random:RandomString | ||
properties: | ||
# Must be a number. Taken from config. | ||
length: ${stringLength} | ||
# Must be an array of key-value pairs. Built from the config and hard-coded values (see above). | ||
keepers: ${keepersArrayCombined} | ||
# Must be a boolean. Taken from config. | ||
lower: ${lowerCaseSettings.uselower} | ||
# Must be a number. Calculated value based on boolean logic and math using the Command provider (see below). | ||
minLower: ${lowerCaseSettings.minLower} | ||
|
||
# Since we don't yet have math operations (other than `sum`) in YAML, | ||
# see https://github.com/pulumi/pulumi-std/issues/70 | ||
# we can use the Pulumi Command resource to do math. | ||
# The output is then referenced by the `lowerCaseSettings` variable. | ||
calculateMinLower: | ||
type: command:local:Command | ||
properties: | ||
# we want about a quarter of the password to be lowercase letters if useLowerCase is true. | ||
create: if ${useLowerCase}; then echo "${stringLength} / 4" | bc; else echo 0; fi | ||
|
||
|
||
# Stack outputs | ||
outputs: | ||
# Generated string | ||
randomString: ${randomString.result} | ||
# Lowercase settings reflecting the config-based value and the calculated minLower value. | ||
lowerCaseSettings: ${lowerCaseSettings} | ||
# The keepers array that was built using the config and hard-coded values. | ||
keepersArrayCombined: ${keepersArrayCombined} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Math and Collection and String Manipulation in YAML | ||
|
||
In addition to programming languages such as Python, Go, Typescript, C#, Pulumi also supports YAML. | ||
However, YAML is limited when it comes to constructs such as loops and conditionals and it is not always obvious how one can do math in a Pulumi YAML program. | ||
Similarly, using the `pulumi-std` library can be a little tricky. | ||
|
||
This project is meant to provide some YAML program examples for these use-cases. | ||
|
||
## References | ||
* [Pulumi YAML Docs Page](https://www.pulumi.com/docs/iac/languages-sdks/yaml/) | ||
* [Pulumi YAML Language Reference](https://www.pulumi.com/docs/iac/languages-sdks/yaml/yaml-language-reference/) | ||
* [pulum-std Function List](https://github.com/pulumi/pulumi-std/blob/master/FUNCTION_LIST.md) | ||
* These are functions that are available to YAML programs. | ||
|
||
## Tips and Tricks for Using the pulumi-std Functions | ||
Start with the functions list page in the `pulumi-std` repo, [pulum-std Function List](https://github.com/pulumi/pulumi-std/blob/master/FUNCTION_LIST.md) | ||
Here you will find the list of functions that are available. | ||
|
||
To understand how to use a given function, click on the link from the function list page. | ||
This will take you to the go code for the function. | ||
From here you can learn two important things: | ||
* What the function does. | ||
* What the function's input parameters are. | ||
|
||
To understand what the function does, look for the `Annotate` function code block. This will provide an explanation of what the function does. | ||
|
||
To understand the function's inputs, look for the `...Args` structure code block. This will list the inputs' names and types (e.g. string, array, etc). | ||
|
||
For example, look at [std-merge](https://github.com/pulumi/pulumi-std/blob/master/std/merge.go). | ||
You'll see it expects a single parameter named `input` that is an array of map of strings. | ||
So something like: `[goo:"foo", moo:"boo"]` and if you look at the Pulumi YAML program in this folder you'll see how that is represented in YAML. | ||
|
||
Now, look at [std-split](https://github.com/pulumi/pulumi-std/blob/master/std/split.go) and you'll see it wants two parameters: `separator` and `text`. | ||
|
||
## Using the Pulumi Program | ||
Read the `Pulumi.yaml` file to see what the program does and how it does it. | ||
|
||
Then, from the folder containing the program: | ||
```bash | ||
$ pulumi stack init dev | ||
$ pulumi up | ||
``` | ||
|
||
This creates a random string and outputs some values used in the code. | ||
|
||
Now, tinker with the stack config values in `Pulumi.yaml` or via `pulumi config set` commands to see what happens when you: | ||
* Change the length of the string. | ||
* Change `length` to, say, `32` | ||
* Run `pulumi up` and you should see that `minLower` is now set to one-fourth(ish) of whatever value you set for the length and there are at least that many lowercase letters in the string. | ||
* Disable using lowercase characters. | ||
* Change `useLowerCase` to `false` | ||
* Run `pulumi up` and you should see that there are no lowercase characters and the stack output show `minLower` set to 0. | ||
* Change one of the key-value pairs in `configKeepersArray`. | ||
* Run `pulumi up` and see that the array map is updated and that a new string is generated since that's what the `keepers` property is for - to trigger a regeneration of the key even though no property directly related to the resource like length, etc is changed.. |