From 80ddc7c0b6746efcf9005f257744a8f79cca2820 Mon Sep 17 00:00:00 2001 From: Carolyn Van Slyck Date: Thu, 6 Jan 2022 11:50:33 -0600 Subject: [PATCH] Blog: IgnoreErrors and Az group command * Explain the new ignoreError feature in the exec mixin * Show how developers can use this functionality to create custom commands for this mixin. Signed-off-by: Carolyn Van Slyck --- docs/content/blog/ignoring-errors.md | 131 +++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 docs/content/blog/ignoring-errors.md diff --git a/docs/content/blog/ignoring-errors.md b/docs/content/blog/ignoring-errors.md new file mode 100644 index 0000000000..71e45e6e95 --- /dev/null +++ b/docs/content/blog/ignoring-errors.md @@ -0,0 +1,131 @@ +--- +title: "Ignoring Mixin Errors and Idempotent Actions" +description: "Porter now supports ignoring the errors from a mixin. The az mixin takes advantage of this new feature to manage resource groups." +date: "2022-01-07" +authorname: "Carolyn Van Slyck" +author: "@carolynvs" +authorlink: "https://twitter.com/carolynvs" +authorimage: "https://github.com/carolynvs.png" +tags: ["mixins"] +summary: | + Porter now supports ignoring the errors from a mixin. The az mixin takes advantage of this new feature to manage resource groups. +--- + +When is an error not really an error? +Questions like this come up regularly when automating deployments with tooling that was designed without state in mind. +What most of us are after is to declare a resource and having our tools ensure that it exists when we need it, and to clean it up when we are done. +However, a lot of command-line tools weren't designed that way. +Calling create twice for the same resource may result in an error because it already exists. +Conversely, deleting a resource twice can trigger an error if the resource doesn't exist anymore. + +This is something that mixins can help with! +The exec mixin now lets you handle errors without having to fall back to using bash. + +Let's take a look at a few different ways that you can handle errors from the exec mixin. + +## Ignore All Errors + +Sometimes you want to run a command but don't really care if it fails. +Now I won't tell you what to do in production, but when debugging a bundle, this can be handy. + +The snippet below will run a command, and Porter will ignore any errors returned by the command, and continue executing the next step in the action. + +```yaml +install: + - exec: + description: "This may not work but such is life" + command: ./buy-me-coffee.sh + ignoreError: + all: true # Ignore any errors from this command +``` + +## Ignore Exit Codes + +Sometimes you get lucky, and the command that you are using has well-defined exit codes. +In the example below, the made-up thing command returns 2 when the resource already exists. +We can check for that and ignore an error when we try to create a thing that already exists. + +You can ignore multiple exit codes, and if any match, then the command's error is ignored. + +```yaml +install: + - exec: + description: "Ensure thing exists" + command: thing + arguments: + - create + ignoreError: + exitCodes: [2] +``` + +## Ignore Output Containing a String + +Usually we aren't so lucky, and we have to scrape the contents of standard error to figure out what went wrong. +Continuing our efforts to create idempotent resources, we can ignore the error when it contains "thing already exits". + +```yaml +install: + - exec: + description: "Ensure thing exists" + command: thing + arguments: + - create + ignoreError: + output: + contains: ["thing already exists"] +``` + +## Ignore Output Matching a Regular Expression + +Finally, there are times when the error message is a bit more difficult to parse, so we fall back to our favorite hammer: regular expressions. +In the example below, when we delete a thing that has already been deleted, "thing NAME not found" is printed to standard error. +We can use a Go regular expression to match the error message. +I recommend using [regex101.com](https://regex101.com/) to test out your regular expression with the Golang syntax enabled. + +```yaml +uninstall: + - exec: + description: "Make the thing go away" + command: thing + arguments: + - remove + ignoreError: + output: + regex: "thing (.*) not found" +``` + +## Create Custom Idempotent Mixin Commands + +Whenever possible, I encourage you to avoid the exec mixin and use a custom mixin for the tooling that you are automating. +For example, if you are automating terraform, use the [terraform mixin](https://porter.sh/mixins/terraform/). +Mixins are meant to adapt a tool to work well inside a bundle. + +I used the new ignore errors capability of the exec mixin's library to create a new custom command for the [az mixin](https://porter.sh/mixins/az/). +The **group** command allows you to declare a resource group, and the mixin will handle creating it if it doesn't exist, and cleaning it up when the bundle is uninstalled. + +```yaml +install: + - az: + description: "Ensure my resource group exists" + group: + name: mygroup + location: eastus2 + +uninstall: + - az: + description: "Remove my resource group" + group: + name: mygroup +``` + +These mixin commands are idempotent and handle errors automatically for you. +This lets you focus on the resources you need, and spend less time figuring out how to automate a command-line tool to work in a way it wasn't designed for. + +## Try it out + +Bundle authors, try out moving some of that custom error handling logic out of bash scripts and move it into your exec mixin calls. +Mixin authors, take a look at how the az mixin uses the exec mixin library to add error handling. +You can quickly add the same functionality from the exec mixin to yours, or create a custom command that manages the error handling automatically. + +Give it a try and let us know how it works for you! +If there is a mixin that you would like to use this new error handling with, let us know, and we can help make that happen more quickly.