-
Notifications
You must be signed in to change notification settings - Fork 213
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
Blog: IgnoreErrors and Az group command #1854
Changes from 1 commit
db34c53
ece3fd6
b3d88ad
98569ae
b23139e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
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. | ||
For example, when I repeat a script that creates a resource, I don't want it to error out because the resource already exists. | ||
A lot of command-line tools weren't designed in a way that works well with bundles. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
An installation could fail halfway through and need to be repeated. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This is why we encourage bundle authors to use custom mixins, instead of just the exec mixin, because mixins are designed to work with bundles and give you **idemponent** behavior. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Mixins should do what's necessary to match the desired state in the bundle and handle recoverable errors. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Since we can't have a custom mixin for every tool and situation though, the exec mixin just got smarter. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
You can now handle errors directly from the exec mixin without having to fall back to writing scripts. | ||
|
||
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. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
We can check for that and ignore the 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. | ||
|
||
Regular expressions being the tricky devils they are, I recommend using [regex101.com](https://regex101.com/) to quickly test and iterate on your regular expression. | ||
|
||
```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 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. | ||
|
||
The example mixin, Skeletor, has been updated with an example custom command to help get you started. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 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. | ||
carolynvs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Mixin authors, take a look at how the az mixin uses the exec mixin library to add error handling. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we link to the PR adding the logic in the az mixin? Or maybe source code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The more I thought about it the more I think that just looking at an existing mixin is pretty hard to figure out what's going on. I will hold off on the blog post and implement this stuff in skeletor with lots of comments so that we can point people to that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once getporter/skeletor#31 is merged I'll link to the source code that demonstrates how to do this in skeletor |
||
You can quickly add the same error handling behavior to your mixin, or create a custom command that handles errors 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the question? (The when is an error not really an error) and more something like .. Why is my automated deployment erroring out when the resources exist? or something else. It's almost like when is an error not really an error is presupposing folks understanding what's up with the feature that based on me not being as steeped in what's going on with Porter really confused me at first by the title/description even.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll rework it so that it's less clever and more clear. 👍