{"id":37165974,"url":"https://github.com/ian-d/ecs-template","last_synced_at":"2026-01-14T19:40:10.960Z","repository":{"id":64303274,"uuid":"149504798","full_name":"ian-d/ecs-template","owner":"ian-d","description":"AWS KMS and SSM / Parameter Store-aware Go template file parsing for AWS ECS containers.","archived":false,"fork":false,"pushed_at":"2019-09-16T15:31:17.000Z","size":19,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-20T06:27:12.812Z","etag":null,"topics":["aws","ecs","kms","ssm"],"latest_commit_sha":null,"homepage":"","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/ian-d.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}},"created_at":"2018-09-19T19:54:36.000Z","updated_at":"2020-08-31T16:28:22.000Z","dependencies_parsed_at":"2023-01-15T10:00:32.989Z","dependency_job_id":null,"html_url":"https://github.com/ian-d/ecs-template","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ian-d/ecs-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ian-d%2Fecs-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ian-d%2Fecs-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ian-d%2Fecs-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ian-d%2Fecs-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ian-d","download_url":"https://codeload.github.com/ian-d/ecs-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ian-d%2Fecs-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28432672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T18:57:19.464Z","status":"ssl_error","status_checked_at":"2026-01-14T18:52:48.501Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","ecs","kms","ssm"],"created_at":"2026-01-14T19:40:09.965Z","updated_at":"2026-01-14T19:40:10.954Z","avatar_url":"https://github.com/ian-d.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ecs-template\n\nAWS's [Elastic Container Service](https://aws.amazon.com/ecs/) has a secrets problem: AWS provides services like [SSM/Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html) and [KMS](https://aws.amazon.com/kms/) for secret management but they are not integrated into ECS task definitions. This is left up to the user, leading to unnecessary container dependencies for custom entrypoints (bigger images, more per-application code) or SSM/KMS aware containerized applications (not very 12 Factor-y).\n\n`ecs-template` provides a single, small binary that provides helpful ENV/SSM/KMS functions for [Go template](https://golang.org/pkg/text/template/) files stored locally or fetched from external sources (S3, Git, HTTP). Once `ecs-template` has moved the source files, directories, and archives (described below) to their destinations on the local filesystem it then parses the destination files in-place as if they were a [Go template](https://golang.org/pkg/text/template/).\n\nAs part of an entrypoint shell script for Docker containers running in ECS it provides a simple way to have external per-environment configuration bundles in S3 and keep applications SSM/KMS agnostic by externalizing secret fetching.\n\n## Basic Usage\n```\n$ aws ssm put-parameter \\\n  --name 'my_app_username' \\\n  --type \"SecureString\" \\\n  --value 'scott'\n\n$ aws ssm put-parameter \\\n  --name 'my_app_password' \\\n  --type \"SecureString\" \\\n  --value 'tiger'\n\n$ cat example.tmpl\nusername={{ ssm \"my_app_username\" true }}\npassword={{ ssm \"my_app_password\" true }}\n\n$ ecs-template -f \"example.tmpl, example.out\"\n2018/09/19 15:34:11 Fetching file example.tmpl to destination example.out\n2018/09/19 15:34:11 Template parsing file: example.out\n\n$ cat example.out\nusername=scott\npassword=tiger\n```\n\nOr using a local file to export secrets as ENV vars:\n```\n$ cat env.tmpl\nexport MY_APP_USERNAME={{ ssm \"my_app_username\" true }}\nexport MY_APP_PASSWORD={{ ssm \"my_app_password\" true }}\n\n$ ecs-template -f \"env.tmpl, env.out\" \\\n  \u0026\u0026 source env.out \\\n  \u0026\u0026 rm env.out\n2018/09/19 15:50:40 Fetching file env.tmpl to destination env.out\n2018/09/19 15:50:40 Template parsing file: env.out\n\n$ env | grep MY_APP\nMY_APP_USERNAME=scott\nMY_APP_PASSWORD=tiger\n```\n\n## Template Functions\n`ecs-template` provides template functions to fetch secrets from AWS services. All of the template functions from [sprig](http://masterminds.github.io/sprig/) are also included.\n\n### `ssm \u003ckey\u003e \u003cisEncryted\u003e`\nReturns the value of the SSM `\u003ckey\u003e` and requires a `true|false` value for `\u003cisEncrypted\u003e` (no default value):\n```\nusername={{ ssm \"my_app_username\" false }}\npassword={{ ssm \"my_app_password\" true }}\n```\n\n### `ssmPath \u003cpath\u003e \u003cisEncrypted\u003e \u003crecursive\u003e`\nReturns a list of fully path-qualified keys and values. Assume the paths `/app/prod/db/password` and `/app/prod/db/username` exist and `ENV` environment variable is `prod`:\n```\n{{ $base := (print \"/app/\" (env \"ENV\")) -}}\n{{ $creds := (ssmPath $base true true) -}}\nusername={{ index $creds (print $base \"/db/username\") }}\npassword={{ index $creds (print $base \"/db/password\") }}\n```\n\n### `ssmJSON \u003ckey\u003e \u003cisEncrypted\u003e`\nAssumes the value of `\u003ckey\u003e` is JSON, parses it, and returns a map. Assume the value for SSM key `my_app` is `{ username: \"foo\", password: \"bar\" }`:\n```\nusername={{ (ssmJSON \"my_app\" false).username }}\npassword={{ (ssmJSON \"my_app\" false).password }}\n```\n\n### `kms \u003cbase64blob\u003e`\nAssumes `base64blob` is a Base64-encoded KMS ciphertext blob:\n\n```\nusername={{ kms (env \"APP_USER_ENC\") }}\npassword={{ kms (env \"APP_PASSWORD_ENC\") }}\n```\n\n## Sources \u0026 External Locations\nAll source locations may be either local files/directories or any of the external URL formats supported by go-getter: [go-getter URL formats](https://github.com/hashicorp/go-getter#url-format), which includes git, http, s3.\n\nBefore being fetched/moved, all source arguments are first parsed as templates, allowing sources to be dynamically defined:\n```\n$ ecs-template \\\n  --dir \"my-bucket.bucket.s3.amazonaws.com/{{env \"ENV\"}}-config.tar.gz, /home/app/config\"\n  --file \"\"\n```\n\n### Directories \u0026 Archives (`--dir \u003csource, dest\u003e`)\nArchives are automatically unpacked into the `\u003cdest\u003e` directory, which will be created if it does not exist. Supported archive formats are those included by default by [go-getter](https://github.com/hashicorp/go-getter#unarchiving).\n\n### Globs (`--glob \u003cpattern\u003e`)\nGlobs are considered to be in-place file templates, but are not evaluated until after directories and archives have been moved and unpacked. (Except in manifests, see below.) Globs can therefore refer to files that only exist once an archive/dir has been moved:\n```\n$ ecs-template \\\n  --dir \"my-bucket.bucket.s3.amazonaws.com/{{env \"ENV\"}}-config.tar.gz, /home/app/config\"\n  --glob \"/home/app/config/**/*.conf\"\n```\nRecursive matches with `**` are supported, but `~` for home directories is not. Be sure to quote globs flags so they don't go through shell expansion.\n\n### Files (`--file \u003csource\u003e, \u003cdest\u003e` or `--file \u003cdest\u003e`)\nFiles are either `\u003csource\u003e,\u003cdest\u003e` pairs where the source location is copied to the destination location (full path + filename) before the destination location is parsed as a template. Using just `\u003cdest\u003e` means the file will be parsed as a template *in place*. Using just `\u003cdest\u003e` will **overwrite** the file with the results of the template parsing, ***so be very careful***. It is intended to be used inside a container.\n\n### Manifests (`--manifest \u003csource\u003e`)\nManifests are YAML files that list directories, globs, and files to parse. This is useful for per-env or generic container reuse (eg, a generic Tomcat image that pulls different configurations/secrets at launch):\n\n```\necs-template \\\n  --manifest \"my-bucket.bucket.s3.amazonaws.com/{{env \"ENV\"}}.yaml\"\n```\n\nAn example manifest YAML:\n```\ndirs:\n  - \"my-bucket.bucket.s3.amazonaws.com/{{env \"ENV\"}}-config.tar.gz, /home/app/config\"\nglobs:\n  - \"/home/app/config/**/*.conf\"\n  - \"/home/app/config/**/*.yaml\"\nfiles:\n  - \"/home/app/config/app.env\"\n```\n\nMultiple `--manifest` flags may be used, but directories and globs are evaluated at manifest parse time, per manifest.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fian-d%2Fecs-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fian-d%2Fecs-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fian-d%2Fecs-template/lists"}