|
1 | 1 | # Authoring your first patch
|
2 | 2 |
|
3 |
| -This page is under construction. |
| 3 | +## Prerequisites |
| 4 | +* You have familiarity with Terraform or OpenTofu |
| 5 | +* You have [patcher installed](/2.0/docs/patcher/installation/) either locally or as a GitHub Actions Workflow in your repository |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +In this tutorial we will walk you through the following steps: |
| 10 | + |
| 11 | +**Authoring a Patch**: |
| 12 | +* Identifying the breaking change and its remediation steps |
| 13 | +* Running `patcher generate` to template the patch |
| 14 | +* Filling out the patch fields |
| 15 | +* Modifying `config.yaml` |
| 16 | + |
| 17 | +### Test Module |
| 18 | + |
| 19 | +In this tutorial we'll use the `patcher-test` module from the `gruntwork-io/terraform-aws-utilities` repository. This module has a version `v0.10.3` that we'll intentionally specify as outdated in our infrastructure unit, and we'll write a patch to go out with the `v0.10.4` release. You can find the full, real-world example [here](https://github.com/gruntwork-io/terraform-aws-utilities/pull/102/), but we'll walk through the steps to arrive there below. |
| 20 | + |
| 21 | +## Identifying the Breaking Change and its Remediation Steps |
| 22 | + |
| 23 | +Let's say you want to add a new required variable to the `patcher-test` module. |
| 24 | +This type of change definitely counts as a breaking change, because if consumers of your module don't update their attributes to include the new variable, then OpenTofu will fail to plan/apply the infrastructure going forward. |
| 25 | + |
| 26 | +<!-- spell-checker: disable --> |
| 27 | +Add the new `sampleinput` variable to `variables.tf`: |
| 28 | + |
| 29 | +```hcl title="$$DIRECTORY$$/variables.tf" |
| 30 | +variable "sampleinput" { |
| 31 | + type = string |
| 32 | + description = "Sample input for the module" |
| 33 | + default = "unset-value" |
| 34 | +} |
| 35 | +``` |
| 36 | +<!-- spell-checker: enable --> |
| 37 | + |
| 38 | +## Running `patcher generate` to template the patch |
| 39 | + |
| 40 | +Then, run `patcher generate` in the root of the git repo to generate the patch template, given the title of the patch: |
| 41 | + |
| 42 | +```bash |
| 43 | +$ patcher generate "Sample Breaking Change" |
| 44 | +``` |
| 45 | + |
| 46 | +This command adds a templated patch to your repo with the path `.patcher/patches/sample-breaking-change/patch.yaml`: |
| 47 | + |
| 48 | +```yaml title=".patcher/patches/sample-breaking-change/patch.yaml" |
| 49 | +name: "Sample Breaking Change" |
| 50 | +description: <REPLACE_ME> |
| 51 | +author: <REPLACE_ME> |
| 52 | + |
| 53 | +# Optional list of dependencies that the patch requires. |
| 54 | +dependencies: |
| 55 | + - name: terrapatch |
| 56 | + version: "0.1.0" |
| 57 | + |
| 58 | +# List of steps that this patch should execute. |
| 59 | +# Each step has a name field (string) and a run field, which can denote either an OS command, or an external script to be run. |
| 60 | +# If there are any external scripts, then make sure you include these in the same directory where the patch.yaml file is. |
| 61 | +steps: |
| 62 | + - name: <REPLACE_ME> |
| 63 | + run: <REPLACE_ME> |
| 64 | + - name: <REPLACE_ME> |
| 65 | + run: <REPLACE_ME> |
| 66 | +``` |
| 67 | +
|
| 68 | +As the module maintainer, you'll fill in the `<REPLACE_ME>` fields as necessary: |
| 69 | +* `description`: Describe the change in a full sentence, in a way that succinctly communicates the change. |
| 70 | +* `author`: The author of the patch. This entry could be you, or an organization, or anything else appropriate. |
| 71 | +* `steps.name`: A short label for that particular step. |
| 72 | +* `steps.run`: The command to run to perform that particular step. |
| 73 | + |
| 74 | +## Filling out the Patch Fields |
| 75 | + |
| 76 | +Because this breaking change is pretty simple, we can use [`terrapatch`](https://github.com/gruntwork-io/terrapatch) to perform the one necessary step: |
| 77 | + |
| 78 | +<!-- spell-checker: disable --> |
| 79 | +```bash |
| 80 | +$ terrapatch add-module-argument $PATCHER_MODULE_ADDRESS sampleinput "\"samplevalue\"" |
| 81 | +``` |
| 82 | +<!-- spell-checker: enable --> |
| 83 | + |
| 84 | +`$PATCHER_MODULE_ADDRESS` gets populated when Patcher is run; it doesn't need to be set independently anywhere. |
| 85 | + |
| 86 | +Once the fields in the patch are filled out, the patch should look like this: |
| 87 | + |
| 88 | +<!-- spell-checker: disable --> |
| 89 | +```yaml |
| 90 | +name: "Sample Breaking Change" |
| 91 | +description: A sample breaking change that adds a new argument |
| 92 | +author: Gruntwork |
| 93 | +
|
| 94 | +# Optional list of dependencies that the patch requires. |
| 95 | +dependencies: |
| 96 | + - name: terrapatch |
| 97 | + version: "0.1.0" |
| 98 | +
|
| 99 | +# List of steps that this patch should execute. |
| 100 | +# Each step has a name field (string) and a run field, which can denote either an OS command, or an external script to be run. |
| 101 | +# If there are any external scripts, then make sure you include these in the same directory where the patch.yaml file is. |
| 102 | +steps: |
| 103 | + - name: |
| 104 | + run: terrapatch add-module-argument $PATCHER_MODULE_ADDRESS sampleinput "\"samplevalue\"" |
| 105 | +``` |
| 106 | +<!-- spell-checker: enable --> |
| 107 | + |
| 108 | +## Modifying `config.yaml` |
| 109 | + |
| 110 | +Next, you'll need to update the `.patcher/config.yaml` file to reflect that a new patch is added in your repo. |
| 111 | +Think of the `config.yaml` file like an index of patches for the repo. |
| 112 | +Patcher uses it to quickly identify if there are dependencies to incorporate, given a version bump to examine. |
| 113 | + |
| 114 | +The general structure of an entry in `config.yaml` is the following: |
| 115 | + |
| 116 | +```yaml |
| 117 | + - tag: <VERSION> |
| 118 | + patches: |
| 119 | + - slug: "<PATCH_NAME_SLUG>" |
| 120 | + modules_affected: |
| 121 | + - <MODULE_NAME> |
| 122 | +``` |
| 123 | + |
| 124 | +The following fields are defined as: |
| 125 | +* `<VERSION>`: the version of the module that introduces the breaking change |
| 126 | +* `<PATCH_NAME_SLUG>`: the slug that the patch uses as its directory name |
| 127 | +* `<MODULE_NAME>`: the name of the module that includes the breaking change |
| 128 | + |
| 129 | +Once the fields are filled out, the new entry to the `config.yaml` file will look like this: |
| 130 | + |
| 131 | +```yaml |
| 132 | + - tag: v0.10.4 |
| 133 | + patches: |
| 134 | + - slug: "sample-breaking-change" |
| 135 | + modules_affected: |
| 136 | + - patcher-test |
| 137 | +``` |
| 138 | + |
| 139 | +Include all changes to `config.yaml`, the new `patch.yaml` file, and the changes to the terraform module in one single release (typically, this is one single PR also, but that's not a requirement). |
| 140 | +Other users of Patcher will receive the updates the next time they run `patcher update`, and benefit from the work done here. |
| 141 | + |
| 142 | +:::info |
| 143 | +Using `patcher` to test patches is not supported at this time. |
| 144 | +The best strategy at this moment is to test steps manually and locally. |
| 145 | +Future updates to patcher will include additional mechanisms to make testing new patches easier. |
| 146 | +::: |
0 commit comments