{"id":14530562,"url":"https://github.com/dhth/outtasync","last_synced_at":"2026-01-04T23:51:18.812Z","repository":{"id":225425925,"uuid":"765970215","full_name":"dhth/outtasync","owner":"dhth","description":"Identify cloudformation stacks that are not in sync with their template files","archived":false,"fork":false,"pushed_at":"2024-05-28T22:00:51.000Z","size":2004,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-29T01:52:51.031Z","etag":null,"topics":["bubbletea","cloudformation","tui"],"latest_commit_sha":null,"homepage":"https://tools.dhruvs.space/outtasync","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dhth.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-02T01:43:36.000Z","updated_at":"2024-06-22T09:10:55.901Z","dependencies_parsed_at":"2024-06-22T09:24:17.000Z","dependency_job_id":null,"html_url":"https://github.com/dhth/outtasync","commit_stats":null,"previous_names":["dhth/outtasync"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhth%2Fouttasync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhth%2Fouttasync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhth%2Fouttasync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dhth%2Fouttasync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dhth","download_url":"https://codeload.github.com/dhth/outtasync/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245401377,"owners_count":20609163,"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":["bubbletea","cloudformation","tui"],"created_at":"2024-09-05T00:01:08.160Z","updated_at":"2026-01-04T23:51:18.806Z","avatar_url":"https://github.com/dhth.png","language":"Go","funding_links":[],"categories":["Applications"],"sub_categories":["Cloud and DevOps"],"readme":"# outtasync\n\n[![Build Workflow Status](https://img.shields.io/github/actions/workflow/status/dhth/outtasync/main.yml?style=flat-square)](https://github.com/dhth/outtasync/actions/workflows/main.yml)\n[![Vulncheck Workflow Status](https://img.shields.io/github/actions/workflow/status/dhth/outtasync/vulncheck.yml?style=flat-square\u0026label=vulncheck)](https://github.com/dhth/outtasync/actions/workflows/vulncheck.yml)\n[![Latest Release](https://img.shields.io/github/release/dhth/outtasync.svg?style=flat-square)](https://github.com/dhth/outtasync/releases/latest)\n[![Commits Since Latest Release](https://img.shields.io/github/commits-since/dhth/outtasync/latest?style=flat-square)](https://github.com/dhth/outtasync/releases)\n\n`outtasync` helps you identify Cloudformation stacks that have drifted or gone\nout of sync with the state represented by their template files.\n\n![tui](https://tools.dhruvs.space/images/outtasync/v2/tui.png)\n\n💾 Installation\n---\n\n**homebrew**:\n\n```sh\nbrew install dhth/tap/outtasync\n```\n\n**go**:\n\n```sh\ngo install github.com/dhth/outtasync@latest\n```\n\nOr get the binary directly from a\n[release](https://github.com/dhth/outtasync/releases). Read more about verifying\nthe authenticity of released artifacts [here](#-verifying-release-artifacts).\n\n🛠️ Pre-requisites\n---\n\n- `git` (used to compute diff for out-of-sync changes)\n    - `outtasync` doesn't change or override git's pager, so the diff will\n        follow your `.gitconfig` settings (if present).\n\n🛠️ Configuration\n---\n\nCreate a configuration file that looks like the following. To determine where\n`outtasync` looks for this file by default on your OS, run `outtasync check -h`\nand look at the output.\n\n```yaml\nstacks:\n  - name: bingo-service-qa\n\n    # use this to provide configuration and credentials via environment variables\n    # https://docs.aws.amazon.com/sdkref/latest/guide/environment-variables.html\n    config_source: env\n    arn: arn:aws:cloudformation:eu-central-1:000000000000:stack/bingo-service-qa/00000000-1111-2222-33333333333333333\n    template_path: ~/projects/bingo-service/cloudformation/infrastructure.yml\n    tags:\n      - qa\n\n  - name: papaya-service-staging\n\n    # use this to leverage a profile contained in the shared AWS config and credentials files\n    # https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html\n    config_source: profile:\u003cPROFILE_NAME\u003e\n    arn: arn:aws:cloudformation:eu-central-1:000000000000:stack/bingo-service-qa/00000000-4444-5555-66666666666666666\n    template_path: https://url.where/your/stack/template/file/is/located/cloudformation.yml\n    remote_call_headers:\n      - key: Authorization\n        value: \"token $STACK_SPECIFIC_TOKEN\"\n      - key: Header\n        value: \"to use for sending request to the url defined by template_path\"\n    tags:\n      - staging\n\n  - name: galactus-service-prod\n\n    # use this when you want to provide configuration and credentials via environment variables\n    # but want to assume another role for performing the actual operations\n    config_source: assume::\u003cIAM_ROLE_ARN\u003e\n    arn: arn:aws:cloudformation:eu-central-1:000000000000:stack/galactus-service-prod/00000000-7777-8888-99999999999999999\n    template_path: \"$SOME_ENV_VAR/path/to/file.yml\"\n    tags:\n      - prod\n\n# these are applied globally to all stacks where template_path is a URL\nremote_call_headers:\n  - key: Authorization\n    value: \"token $GLOBAL_GH_TOKEN\"\n```\n\n⚡️ Usage\n---\n\n`outtasync` provides the following subcommands:\n\n- `outtasync tui`: for opening up outtasync's TUI\n- `outtasync check`: for checking for drift status and template sync status on\n    the command line\n- `outtasync config`: for interacting with outtasync's config\n\n📟 TUI\n---\n\n```text\n$ outtasync tui -h\n\nopen outtasync's tui\n\nUsage:\n  outtasync tui [flags]\n\nFlags:\n  -c, --config-file string   location of outtasync's config file\n  -h, --help                 help for tui\n  -n, --name-filter string   regex for name(s) (configured in outtasync's config) to filter stacks by\n  -t, --tags-filter string   regex for tag(s) to filter stacks by\n```\n\n![tui](https://tools.dhruvs.space/images/outtasync/v2/tui.gif)\n\n### ⌨️ TUI Keymaps\n\n#### General\n\n| Keymap         | What it does     |\n|----------------|------------------|\n| `q`            | go back          |\n| `esc`/`ctrl+c` | quit immediately |\n\n#### Stacks List\n\n| Keymap          | What it does                                                        |\n|-----------------|---------------------------------------------------------------------|\n| `j`/`↓`         | move cursor down                                                    |\n| `k`/`↑`         | move cursor up                                                      |\n| `h`             | go to previous page                                                 |\n| `l`             | go to next page                                                     |\n| `g`             | go to the top                                                       |\n| `G`             | go to the end                                                       |\n| `tab`/`\u003cS-tab\u003e` | move between filter states                                          |\n| `1`             | filter for stacks with code mismatch                                |\n| `2`             | filter for stacks that've drifted                                   |\n| `3`             | filter for stacks with errors                                       |\n| `s`             | check template sync status for stack under cursor (when unfiltered) |\n| `S`             | check template sync status for all stacks (when unfiltered)         |\n| `\u003cctrl+s\u003e`      | show sync check results (requires git to be available in PATH)      |\n| `d`             | check drift status for stack under cursor (when unfiltered)         |\n| `D`             | check drift status for all stacks (when unfiltered)                 |\n| `e`             | show error details (if present)                                     |\n\n📋 Check\n---\n\n```text\n$ outtasync check -h\n\ncheck sync and drift status for stacks\n\nUsage:\n  outtasync check [flags]\n\nFlags:\n  -D, --check-drift                 check drift status (only applicable in cli mode) (default true)\n  -T, --compare-template            compare actual template with template code (only applicable in cli mode)\n  -c, --config-file string          location of outtasync's config file\n  -f, --format string               output format [possible values: default, delimited, html] (default \"default\")\n  -h, --help                        help for check\n  -o, --html-open                   open html output in browser instead of outputting to stdout\n      --html-template-file string   location of the template file to use for html output\n      --html-title string           title of the html output (default \"outtasync\")\n  -N, --list-negatives-only         list negatives only\n  -n, --name-filter string          regex for name(s) (configured in outtasync's config) to filter stacks by\n  -p, --progress-indicator          whether to show progress indicator (only applicable in cli mode) (default true)\n  -t, --tags-filter string          regex for tag(s) to filter stacks by\n```\n\nThe `check` subcommand can output results in 3 formats: ansi colored text,\ndelimited, and HTML.\n\n### Normal output\n\n```bash\nouttasync check -n '(customer|auth)' -T=1 -D=0\n```\n\n![check](https://tools.dhruvs.space/images/outtasync/v2/check.gif)\n\n### Delimited output\n\n```bash\nouttasync check -n '(customer|auth)' -T=1 -D=0 -f delimited | tbll\n```\n\n![check](https://tools.dhruvs.space/images/outtasync/v2/check-delimited.png)\n\n### HTML output\n\n```bash\nouttasync check -n '(customer|auth)' -T=1 -D=0 -f html\n```\n\n![html](https://tools.dhruvs.space/images/outtasync/v2/html-1.png)\n\n![html](https://tools.dhruvs.space/images/outtasync/v2/html-2.png)\n\n🧰 Config\n---\n\n`outtasync` allows you to generate its own config.\n\n```text\n$ outtasync config generate\n\ngenerate sample config\n\nUsage:\n  outtasync config generate [flags]\n\nFlags:\n  -c, --config-source string   config source to use (default \"env\")\n  -h, --help                   help for generate\n  -n, --name-filter string     regex for name(s) to filter stacks by\n  -t, --tags string            comma separated list of tags to use\n```\n\nYou can also validate a config file using `outtasync config validate`.\n\n🔐 Verifying release artifacts\n---\n\nIn case you get the `outtasync` binary directly from a\n[release](https://github.com/dhth/outtasync/releases), you may want to verify\nits authenticity. Checksums are applied to all released artifacts, and the\nresulting checksum file is signed using\n[cosign](https://docs.sigstore.dev/cosign/installation/).\n\nSteps to verify (replace `x.y.z` in the commands listed below with the version\nyou want):\n\n1. Download the following files from the release:\n\n   - outtasync_x.y.z_checksums.txt\n   - outtasync_x.y.z_checksums.txt.pem\n   - outtasync_x.y.z_checksums.txt.sig\n\n2. Verify the signature:\n\n   ```shell\n   cosign verify-blob outtasync_x.y.z_checksums.txt \\\n       --certificate outtasync_x.y.z_checksums.txt.pem \\\n       --signature outtasync_x.y.z_checksums.txt.sig \\\n       --certificate-identity-regexp 'https://github\\.com/dhth/outtasync/\\.github/workflows/.+' \\\n       --certificate-oidc-issuer \"https://token.actions.githubusercontent.com\"\n   ```\n\n3. Download the compressed archive you want, and validate its checksum:\n\n   ```shell\n   curl -sSLO https://github.com/dhth/outtasync/releases/download/vx.y.z/outtasync_x.y.z_linux_amd64.tar.gz\n   sha256sum --ignore-missing -c outtasync_x.y.z_checksums.txt\n   ```\n\n3. If checksum validation goes through, uncompress the archive:\n\n   ```shell\n   tar -xzf outtasync_x.y.z_linux_amd64.tar.gz\n   ./outtasync\n   # profit!\n   ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhth%2Fouttasync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdhth%2Fouttasync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdhth%2Fouttasync/lists"}