{"id":26361160,"url":"https://github.com/polyseam/example-cndi-templates","last_synced_at":"2026-02-13T15:07:07.505Z","repository":{"id":160041102,"uuid":"614524293","full_name":"polyseam/example-cndi-templates","owner":"polyseam","description":"demonstration of how to write cndi templates","archived":false,"fork":false,"pushed_at":"2023-06-29T02:14:53.000Z","size":192,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-01T07:19:03.964Z","etag":null,"topics":["cndi"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polyseam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2023-03-15T19:02:47.000Z","updated_at":"2023-03-27T18:36:25.000Z","dependencies_parsed_at":"2023-07-16T11:16:35.319Z","dependency_job_id":null,"html_url":"https://github.com/polyseam/example-cndi-templates","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/polyseam/example-cndi-templates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polyseam%2Fexample-cndi-templates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polyseam%2Fexample-cndi-templates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polyseam%2Fexample-cndi-templates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polyseam%2Fexample-cndi-templates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polyseam","download_url":"https://codeload.github.com/polyseam/example-cndi-templates/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polyseam%2Fexample-cndi-templates/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29411138,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["cndi"],"created_at":"2025-03-16T17:20:09.727Z","updated_at":"2026-02-13T15:07:07.416Z","avatar_url":"https://github.com/polyseam.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# example-cndi-templates\n\nThere are a few example templates here to help you get started in building your\nown! The smallest one can be found [here](aws/tiny.jsonc).\n\n```bash\ncndi init --interactive --template https://raw.githubusercontent.com/polyseam/example-cndi-templates/main/aws/tiny.jsonc\n```\n\n![secret-app-commands](img/secret-app-example.png)\n\n---\n\n## Wbat is a CNDI Template?\n\nA\n[cndi](https://cndi.run/gh?utm_content=gh_cndi_template_readme\u0026utm_campaign=cndi_template_readme_v1\u0026utm_source=github.com/polyseam/cndi-template-basic\u0026utm_medium=repo\u0026utm_id=1007)\nTemplate is a JSON file that CNDI can parse in order to provide a simplified\ndeployment experience for some cloud-native application. The template declares 3\n`\"output\"` blocks, each relating to a particular file, and one `\"prompts\"` array\nwhich allows each output to be customized by end users. Let's start by looking\nat the `\"prompts\"` array.\n\n## prompts\n\nThe `prompts` array is a list of questions that CNDI will ask the user when they\nrun `cndi init --interactive`, if the user is not in interactive mode the value\nwill fallback to the default provided.\n\n```jsonc\n{\n  \"prompts\": [\n    {\n      // each prompts object is created leveraging the `prompts` module from\n      // https://cliffy.io/docs/prompt#prompt-list\n      // the following input types are all supported:\n      // \"Input\" | \"Secret\" | \"Confirm\" | \"Toggle\" | \"Select\" | \"List\" | \"Checkbox\" | \"Number\"\n      \"type\": \"Input\",\n      \"name\": \"argocdDomainName\",\n      \"message\": \"What domain name should argocd be deployed on?\",\n      \"default\": \"argocd.example.com\"\n    },\n    {\n      \"type\": \"Secret\",\n      \"name\": \"myAirflowPassword\",\n      \"message\": \"Please enter a default password for Airflow:\",\n      \"default\": \"admin\"\n    }\n  ]\n}\n```\n\nWhen using the `--interactive` flag in CNDI each of these prompts will provide\nan interactive prompt to populate the value.\n\nIf the user does not provide a value _or_ if the user is not using interactive\nmode, the default will be used.\n\nThese values are then accessible inside of a template `\"output\"` using the\nfollowing syntax: `{{ $.cndi.prompts.responses.\u003cprompt_name\u003e }}`.\n\nFor example, if we wanted to use the value of `argocdDomainName` in a template\nwe would use the following syntax:\n`{{ $.cndi.prompts.responses.argocdDomainName }}`.\n\n## outputs\n\n### cndi-config\n\n**Summary**\n\nThe `outputs[\"cndi-config\"]` block is used to provide a templating interface\naround the `cndi-config.jsonc` file that acts as the core of each CNDI project.\nThe shape of the object is as follows:\n\n```jsonc\n{\n  \"outputs\": {\n    \"cndi-config\": {\n      \"infrastructure\": {\n        /*...*/\n      },\n      \"cluster_manifests\": {\n        /*...*/\n      },\n      \"applications\": {\n        /*...*/\n      }\n    }\n  }\n}\n```\n\nLet's look at an example of leveraging a `\"prompt\"` entry to populate a value\ninto the `cndi-config.jsonc` file.\n\n**Example**\n\nInput:\n\n```jsonc\n{\n  \"cndi-config\": {\n    \"applications\": {\n      /*...*/\n    },\n    \"infrastructure\": {\n      /*...*/\n    },\n    \"cluster_manifests\": {\n      \"argo-ingress\": {\n        \"apiVersion\": \"networking.k8s.io/v1\",\n        \"kind\": \"Ingress\",\n        \"metadata\": {\n          /*...*/\n        },\n        \"spec\": {\n          \"tls\": [\n            {\n              \"hosts\": [\"{{ $.cndi.prompts.responses.argocdDomainName }}\"],\n              \"secretName\": \"lets-encrypt-private-key\"\n            }\n          ],\n          \"rules\": [\n            {\n              \"host\": \"{{ $.cndi.prompts.responses.argocdDomainName }}\",\n              \"http\": {\n                \"paths\": [\n                  /*...*/\n                ]\n              }\n            }\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\nOutput:\n\n```jsonc\n{\n  \"applications\": {\n    /*...*/\n  },\n  \"infrastructure\": {\n    /*...*/\n  },\n  \"cluster_manifests\": {\n    \"argo-ingress\": {\n      \"apiVersion\": \"networking.k8s.io/v1\",\n      \"kind\": \"Ingress\",\n      \"metadata\": {\n        /*...*/\n      },\n      \"spec\": {\n        \"tls\": [\n          {\n            \"hosts\": [\"myargocd.creedthoughts.comgov.uks\"],\n            \"secretName\": \"lets-encrypt-private-key\"\n          }\n        ],\n        \"rules\": [\n          {\n            \"host\": \"myargocd.creedthoughts.comgov.uks\",\n            \"http\": {\n              \"paths\": [\n                /*...*/\n              ]\n            }\n          }\n        ]\n      }\n    }\n  }\n}\n```\n\n### env\n\n**Summary**\n\nThe `env` block is used to provide a templating interface around the `.env` file\nwhich is used for values which should not be written directly to version\ncontrol. The shape of the object is as follows:\n\n```jsonc\n{\n  \"outputs\":{\n    {...},\n    \"env\": {\n      \"extend_basic_env\": \"aws\",\n      \"entries\": [\n        {\n          \"name\": \"POSTGRES_PORT\",\n          \"value\": \"5432\"\n        }\n      ]\n    }\n  }\n}\n```\n\nThe `extend_basic_env` key is used to extend the built-in `.env` file cndi\nprovides for a given deployment target. CNDI provides the necessary prompts for\neach deployment target so that the `.env` file can be extended after those basic\nvalues are collected. The value of `extend_basic_env` should be the name of the\ndeployment target you wish to extend, for example `gcp`, `azure` or `aws` as\nshown above.\n\nIt's also possible to leverage `\"prompt\"` values here in `outputs[\"env\"]`, let's\nlook at an example:\n\n**Example**\n\nInput:\n\n```jsonc\n{\n  \"prompts\": [\n    {\n      \"name\": \"secretAppPassword\",\n      \"type\": \"Input\",\n      \"message\": \"What password should be used for SecretApp?\"\n    }\n  ],\n  \"outputs\": {\n    \"env\": {\n      \"extend_basic_env\": \"aws\",\n      \"entries\": [\n        {\n          \"name\": \"SECRETAPP_PASSWORD\",\n          \"value\": \"{{ $.cndi.prompts.responses.secretAppPassword }}\"\n        }\n      ]\n    }\n  }\n}\n```\n\nOutput:\n\n```bash\nSECRETAPP_PASSWORD='top_secret123'\n```\n\n### readme\n\n**Summary**\n\nThe final block of a [cndi](https://github.com/polyseam/cndi) template is the\n`readme` block, which behave similarly to the other two sections. We specify a\nreadme block in order to provide a templating interface around the `README.md`\nfile that is generated when a user runs `cndi init`. The shape of the object is\nas follows:\n\n```jsonc\n{\n  \"outputs\": {\n    \"cndi-config\":{...},\n    \"env\":{...},\n    \"readme\": {\n      \"extends_basic_readme\": \"aws\",\n      \"template_section\": \"## This is a sample readme section dedicated to this template\"\n    }\n  }\n}\n```\n\nThe `extends_basic_readme` key is used to extend the `README.md` file for a\ngiven deployment target. CNDI provides the necessary readme section for each\ndeployment target so that the `README.md` file can be extended with more content\nafter those basic readme sections have been written to the file.\n\nThe value of `extends_basic_readme` should be the name of the deployment target\nyou wish to extend, for example `gcp`, `azure` or `aws` as shown above.\n\n**Example**\n\nInput:\n\n```jsonc\n{\n  \"prompts\":[{...}],\n  \"outputs\":{\n    \"cndi-config\":{...},\n    \"env\":{...},\n    \"readme\": {\n      \"extend_basic_readme\": \"aws\",\n      \"template_section\": \"# logging into secret app\\n\\nvisit secretapp.cndi.dev and type in the passphrase \\\"{{ $.cndi.prompts.responses.secretAppPassword }}\\\"\"\n    }\n  }\n}\n```\n\nOutput:\n\n```markdown\n\u003c!-- Lots more content above --\u003e\n\n## aws\n\nThis cluster will be deployed on [Amazon Web Services](https://aws.com). When\nyour cluster is initialized the next step is to go to your domain registrar and\ncreate an CNAME record for your Airflow instance, and another for ArgoCD. Both\nentries should point to the single load balancer that was created for your\ncluster.\n\n## This is a simple readme section that is template specific\n\nneato!\n```\n\n### all together now!\n\n```jsonc\n{\n  \"prompts\": [\n    {...}\n  ],\n  \"outputs\":{\n    \"cndi-config\": {\n      \"infrastructure\":{...},\n      \"cluster_manifests\":{...},\n      \"applications\":{...}\n    },\n    \"env\": {\n      \"extend_basic_env\": \"aws\",\n      \"entries\": [{...}]\n    },\n    \"readme\": {\n      \"extends_basic_readme\": \"aws\",\n      \"template_section\": \"##This is a sample readme\\n\\nneato!\"\n    }\n  }\n}\n```\n\n## Included Examples\n\nThis repository contains example templates for use within\n[cndi](https://github.com/polyseam/cndi). There is at least one unit test within\nthe CNDI project that verifies remote templates are working correctly by\ninstalling a template from this repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyseam%2Fexample-cndi-templates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolyseam%2Fexample-cndi-templates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolyseam%2Fexample-cndi-templates/lists"}