{"id":15287061,"url":"https://github.com/ooaklee/tfnotify","last_synced_at":"2025-10-07T01:31:09.430Z","repository":{"id":62304327,"uuid":"559363611","full_name":"ooaklee/tfnotify","owner":"ooaklee","description":"A CLI command to parse Terraform execution result and notify it to support notifiers i.e, GitHub, Mattermost, Slack etc.","archived":false,"fork":true,"pushed_at":"2022-12-28T08:00:05.000Z","size":436,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-11-27T17:37:12.907Z","etag":null,"topics":["aws-codebuild","circleci","gcp","github","gitlab","gitlab-ci","go","jenkins","mattermost","slack","teamcity","terraform","travis-ci","typetalk"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mercari/tfnotify","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ooaklee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2022-10-29T22:01:12.000Z","updated_at":"2022-10-30T16:38:34.000Z","dependencies_parsed_at":"2023-01-31T06:15:16.871Z","dependency_job_id":null,"html_url":"https://github.com/ooaklee/tfnotify","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Ftfnotify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Ftfnotify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Ftfnotify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ooaklee%2Ftfnotify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ooaklee","download_url":"https://codeload.github.com/ooaklee/tfnotify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235575693,"owners_count":19012156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-codebuild","circleci","gcp","github","gitlab","gitlab-ci","go","jenkins","mattermost","slack","teamcity","terraform","travis-ci","typetalk"],"created_at":"2024-09-30T15:24:05.081Z","updated_at":"2025-10-07T01:31:09.011Z","avatar_url":"https://github.com/ooaklee.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"tfnotify\n========\n\n[![][release-svg]][release] [![][test-svg]][test] [![][goreportcard-svg]][goreportcard]\n\n[release]: https://github.com/mercari/tfnotify/actions?query=workflow%3Arelease\n[release-svg]: https://github.com/mercari/tfnotify/workflows/release/badge.svg\n[test]: https://github.com/mercari/tfnotify/actions?query=workflow%3Atest\n[test-svg]: https://github.com/mercari/tfnotify/workflows/test/badge.svg\n[goreportcard]: https://goreportcard.com/report/github.com/mercari/tfnotify\n[goreportcard-svg]: https://goreportcard.com/badge/github.com/mercari/tfnotify\n\ntfnotify parses Terraform commands' execution result and applies it to an arbitrary template and then notifies it to GitHub comments etc.\n\n## Motivation\n\nThere are commands such as `plan` and `apply` on Terraform command, but many developers think they would like to check if the execution of those commands succeeded.\nTerraform commands are often executed via CI like Circle CI, but in that case you need to go to the CI page to check it.\nThis is very troublesome. It is very efficient if you can check it with GitHub comments or Slack etc.\nYou can do this by using this command.\n\n\u003cimg src=\"./misc/images/1.png\" width=\"600\"\u003e\n\n\u003cimg src=\"./misc/images/2.png\" width=\"500\"\u003e\n\n\u003cimg src=\"./misc/images/3.png\" width=\"600\"\u003e\n\n\u003cimg src=\"./misc/images/4.png\" width=\"500\"\u003e\n\n## Installation\n\nGrab the binary from GitHub Releases (Recommended)\n\nor\n\n```console\n$ go get -u github.com/mercari/tfnotify\n```\n\n\n### What tfnotify does\n\n1. Parse the execution result of Terraform\n2. Bind parsed results to Go templates\n3. Notify it to any platform (e.g. GitHub) as you like\n\nDetailed specifications such as templates and notification destinations can be customized from the configuration files (described later).\n\n## Usage\n\n### Basic\n\ntfnotify is just CLI command. So you can run it from your local after grabbing the binary.\n\nBasically tfnotify waits for the input from Stdin. So tfnotify needs to pipe the output of Terraform command like the following:\n\n```console\n$ terraform plan | tfnotify plan\n```\n\nFor `plan` command, you also need to specify `plan` as the argument of tfnotify. In the case of `apply`, you need to do `apply`. Currently supported commands can be checked with `tfnotify --help`.\n\n### Configurations\n\nWhen running tfnotify, you can specify the configuration path via `--config` option (if it's omitted, it defaults to `{.,}tfnotify.y{,a}ml`).\n\nThe example settings of GitHub and GitHub Enterprise, Slack, [Typetalk](https://www.typetalk.com/) are as follows. Incidentally, there is no need to replace TOKEN string such as `$GITHUB_TOKEN` with the actual token. Instead, it must be defined as environment variables in CI settings.\n\n[template](https://golang.org/pkg/text/template/) of Go can be used for `template`. The templates can be used in `tfnotify.yaml` are as follows:\n\nPlaceholder | Usage\n---|---\n`{{ .Title }}` | Like `## Plan result`\n`{{ .Message }}` | A string that can be set from CLI with `--message` option\n`{{ .Result }}` | Matched result by parsing like `Plan: 1 to add` or `No changes`\n`{{ .Body }}` | The entire of Terraform execution result\n`{{ .Link }}` | The link of the build page on CI\n\nOn GitHub, tfnotify can also put a warning message if the plan result contains resource deletion (optional).\n\n#### Template Examples\n\n\u003cdetails\u003e\n\u003csummary\u003eFor GitHub\u003c/summary\u003e\n\n```yaml\n---\nci: circleci\nnotifier:\n  github:\n    token: $GITHUB_TOKEN\n    repository:\n      owner: \"mercari\"\n      name: \"tfnotify\"\nterraform:\n  fmt:\n    template: |\n      {{ .Title }}\n\n      {{ .Message }}\n\n      {{ .Result }}\n\n      {{ .Body }}\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n  apply:\n    template: |\n      {{ .Title }}\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n```\n\nIf you would like to let tfnotify warn the resource deletion, add `when_destroy` configuration as below.\n\n```yaml\n---\n# ...\nterraform:\n  # ...\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n    when_destroy:\n      template: |\n        ## :warning: WARNING: Resource Deletion will happen :warning:\n\n        This plan contains **resource deletion**. Please check the plan result very carefully!\n  # ...\n```\n\nYou can also let tfnotify add a label to PRs depending on the `terraform plan` output result. Currently, this feature is for Github labels only.\n\n```yaml\n---\n# ...\nterraform:\n  # ...\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n    when_add_or_update_only:\n      label: \"add-or-update\"\n    when_destroy:\n      label: \"destroy\"\n    when_no_changes:\n      label: \"no-changes\"\n    when_plan_error:\n      label: \"error\"\n  # ...\n```\n\nSometimes you may want not to HTML-escape Terraform command outputs.\nFor example, when you use code block to print command output, it's better to use raw characters instead of character references (e.g. `-/+` -\u003e `-/\u0026#43;`, `\"` -\u003e `\u0026#34;`).\n\nYou can disable HTML escape by adding `use_raw_output: true` configuration.\nWith this configuration, Terraform doesn't HTML-escape any Terraform output.\n\n~~~yaml\n---\n# ...\nterraform:\n  use_raw_output: true\n  # ...\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      ```\n      {{ .Body }}\n      ```\n  # ...\n~~~\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFor GitHub Enterprise\u003c/summary\u003e\n\n```yaml\n---\nci: circleci\nnotifier:\n  github:\n    token: $GITHUB_TOKEN\n    base_url: $GITHUB_BASE_URL # Example: https://github.example.com/api/v3\n    repository:\n      owner: \"mercari\"\n      name: \"tfnotify\"\nterraform:\n  fmt:\n    template: |\n      {{ .Title }}\n\n      {{ .Message }}\n\n      {{ .Result }}\n\n      {{ .Body }}\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n  apply:\n    template: |\n      {{ .Title }}\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e{{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n\n      \u003cpre\u003e\u003ccode\u003e{{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFor GitLab\u003c/summary\u003e\n\n```yaml\n---\nci: gitlabci\nnotifier:\n  gitlab:\n    token: $GITLAB_TOKEN\n    base_url: $GITLAB_BASE_URL\n    repository:\n      owner: \"mercari\"\n      name: \"tfnotify\"\nterraform:\n  fmt:\n    template: |\n      {{ .Title }}\n\n      {{ .Message }}\n\n      {{ .Result }}\n\n      {{ .Body }}\n  plan:\n    template: |\n      {{ .Title }} \u003csup\u003e[CI link]( {{ .Link }} )\u003c/sup\u003e\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e {{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n      \u003cpre\u003e\u003ccode\u003e {{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n  apply:\n    template: |\n      {{ .Title }}\n      {{ .Message }}\n      {{if .Result}}\n      \u003cpre\u003e\u003ccode\u003e {{ .Result }}\n      \u003c/pre\u003e\u003c/code\u003e\n      {{end}}\n      \u003cdetails\u003e\u003csummary\u003eDetails (Click me)\u003c/summary\u003e\n      \u003cpre\u003e\u003ccode\u003e {{ .Body }}\n      \u003c/pre\u003e\u003c/code\u003e\u003c/details\u003e\n```\n\u003c/details\u003e\n\n\n\u003cdetails\u003e\n\u003csummary\u003eFor Mattermost\u003c/summary\u003e\n\n```yaml\n---\nci: circleci\nnotifier:\n  mattermost:\n    webhook: $MATTERMOST_WEBHOOK\n    channel: $MATTERMOST_CHANNEL\n    bot: $MATTERMOST_BOT_NAME\nterraform:\n  fmt:\n    template: |\n      {{if .Message}}**`Message`**: {{ .Message }}{{end}}\n      **`Context`**:  [*(Click me) Explore the change(s) further*]( {{ .Link }} )\n      \n      {{if .Result}}\n      ## Result\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n\n      ## Details\n\n      View the summary below\n\n      ```\n      {{ .Body }}\n      ```\n\n  plan:\n    template: |\n      {{if .Message}}**`Message`**: {{ .Message }}{{end}}\n      **`Context`**:  [*(Click me) Explore the change(s) further*]( {{ .Link }} )\n      \n      {{if .Result}}\n      ## Result\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n\n      ## Details\n\n      View the summary below\n\n      ```\n      {{ .Body }}\n      ```\n  \n    when_destroy:\n      template: |\n        ## :warning: WARNING: Resource Deletion will happen :warning:\n\n        This plan contains **resource deletion**. Please check the plan result very carefully!\n  apply:\n    template: |\n      {{if .Message}}**`Message`**: {{ .Message }}{{end}}\n      **`Context`**:  [*(Click me) Explore the change(s) further*]( {{ .Link }} )\n      \n      {{if .Result}}\n      ## Result\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n\n      ## Details\n\n      View the summary below\n\n      ```\n      {{ .Body }}\n      ```\n```\n\n\u003e Note, for `notifier.mattermost.bot` to work override, you must ensure you enable application/ webhook overrides on your Mattermost system. If you do not, the webhook will, by default, take the name of its creator. If you cannot enable application/ webhook overrides, you might have to consider creating a dedicated `tfnotify` Mattermost user account.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFor Slack\u003c/summary\u003e\n\n```yaml\n---\nci: circleci\nnotifier:\n  slack:\n    token: $SLACK_TOKEN\n    channel: $SLACK_CHANNEL_ID\n    bot: $SLACK_BOT_NAME\nterraform:\n  plan:\n    template: |\n      {{ .Message }}\n      {{if .Result}}\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n      ```\n      {{ .Body }}\n      ```\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFor Typetalk\u003c/summary\u003e\n\n```yaml\n---\nci: circleci\nnotifier:\n  typetalk:\n    token: $TYPETALK_TOKEN\n    topic_id: $TYPETALK_TOPIC_ID\nterraform:\n  plan:\n    template: |\n      {{ .Message }}\n      {{if .Result}}\n      ```\n      {{ .Result }}\n      ```\n      {{end}}\n      ```\n      {{ .Body }}\n      ```\n```\n\n\u003c/details\u003e\n\n### Supported CI\n\nCurrently, supported CI are here:\n\n- Circle CI\n- Travis CI\n- AWS CodeBuild\n- TeamCity\n- Drone\n- Jenkins\n- GitLab CI\n- GitHub Actions\n- Google Cloud Build\n\n### Private Repository Considerations\nGitHub private repositories require the `repo` and `write:discussion` permissions.\n\n### Jenkins Considerations\n- Plugin\n  - [Git Plugin](https://wiki.jenkins.io/display/JENKINS/Git+Plugin)\n- Environment Variable\n  - `PULL_REQUEST_NUMBER` or `PULL_REQUEST_URL` are required to set by user for Pull Request Usage\n\n### Google Cloud Build Considerations\n\n- These environment variables are needed to be set using [substitutions](https://cloud.google.com/cloud-build/docs/configuring-builds/substitute-variable-values)\n  - `COMMIT_SHA`\n  - `BUILD_ID`\n  - `PROJECT_ID`\n  - `_PR_NUMBER`\n  - `_REGION`\n- Recommended trigger events\n  - `terraform plan`: Pull request\n  - `terraform apply`: Push to branch\n\n## Committers\n\n * Masaki ISHIYAMA ([@b4b4r07](https://github.com/b4b4r07))\n\n## Contribution\n\nPlease read the CLA below carefully before submitting your contribution.\n\nhttps://www.mercari.com/cla/\n\n## License\n\nCopyright 2018 Mercari, Inc.\n\nLicensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fooaklee%2Ftfnotify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fooaklee%2Ftfnotify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fooaklee%2Ftfnotify/lists"}