{"id":21565808,"url":"https://github.com/hylandsoftware/octoconfigtool","last_synced_at":"2025-06-24T00:38:04.445Z","repository":{"id":38010287,"uuid":"179086779","full_name":"HylandSoftware/OctoConfigTool","owner":"HylandSoftware","description":"A tool to manage application configuration that release using Octopus Deploy","archived":false,"fork":false,"pushed_at":"2022-12-08T04:24:14.000Z","size":81,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-08T15:51:10.378Z","etag":null,"topics":["dotnet-core","octopus-deploy"],"latest_commit_sha":null,"homepage":"","language":"C#","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/HylandSoftware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-02T13:43:01.000Z","updated_at":"2024-03-04T14:53:35.000Z","dependencies_parsed_at":"2023-01-24T10:32:17.467Z","dependency_job_id":null,"html_url":"https://github.com/HylandSoftware/OctoConfigTool","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HylandSoftware%2FOctoConfigTool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HylandSoftware%2FOctoConfigTool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HylandSoftware%2FOctoConfigTool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HylandSoftware%2FOctoConfigTool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HylandSoftware","download_url":"https://codeload.github.com/HylandSoftware/OctoConfigTool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248225653,"owners_count":21068078,"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":["dotnet-core","octopus-deploy"],"created_at":"2024-11-24T10:21:48.508Z","updated_at":"2025-04-10T13:13:51.682Z","avatar_url":"https://github.com/HylandSoftware.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Octopus Config Tool\n\n[![Build Status](https://travis-ci.org/HylandSoftware/OctoConfigTool.svg?branch=master)](https://travis-ci.org/HylandSoftware/OctoConfigTool) [![Coverage Status](https://coveralls.io/repos/github/HylandSoftware/OctoConfigTool/badge.svg?branch=master)](https://coveralls.io/github/HylandSoftware/OctoConfigTool?branch=master)\n\nDotNet Tool: [![OctoConfigTool](https://buildstats.info/nuget/OctoConfigTool)](https://www.nuget.org/packages/OctoConfigTool/)\n\nCake Addin: [![OctoConfig.Core](https://buildstats.info/nuget/OctoConfigTool)](https://www.nuget.org/packages/OctoConfig.Core/)\n\nA tool designed to convert json configuration files into a format usable by Octopus Deploy and upload them to Octopus.\nIt supports several secrets providers and pulls secrets based on values in the flat configuration files.\nWorks with tenanted and non-tenanted deployment schemes.\n\n## Tool Usage\n\nThis tool is published in two ways, as a [dotnet tool](https://www.nuget.org/packages/OctoConfigTool/), and a [cake addin](https://www.nuget.org/packages/OctoConfig.Core/)\n\n### DotNet Tool\n\nInstalling the tool is easy, just type `dotnet tool install OctoConfigTool --global` into a shell. Once it's installed simply typing `OctoConfigTool` will execute the tool. Turning the above into this:\n\n```bash\nOctoConfigTool upload-library -f \"C:\\QA\\appsettings.json\" --library \"API Config\" -e QA \\\n-r api-role -a \"API-KEY\" -o https://octodeploy/api \\\n--merge --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n--variableType JsonConversion\n```\n\n#### Shared Variables\n\n##### Required for ALL commands\n\n- `-a`, `--apikey`\n  - The Octopus API key to use\n- `-o`, `--octotUri`\n  - The Octopus API URI to upload to\n\n##### Optional for all commands\n\n- `-m`, `--merge`\n  - Forces arrays in json file to be merged into one variable, rather than generated with indices\n  - Not required\n  - Defaults to `false`\n- `-v`, `--verbose`\n  - Max verbosity\n  - Not Required\n\n##### Required for Upload commands\n\n- `-f`, `--file`\n  - The json file to parse into variables\n- `-r`, `--roles`\n  - The Octopus role(s) to scope variables to\n  - Separated by a space\n  - Applied to all variables\n  - e.g. `-r api api-role web-role`\n  - At least one required\n- `--variableType`\n  - The type of Octopus variables to convert the json file into\n  - Options are `Environment`, `JsonConversion`, `EnvironmentGlob`\n  - `EnvironmentGlob` makes a comma-separated list of variables, and uploads them as a secret using the variable name `ConcatEnvironmentVars`\n\n##### Optional for Upload commands\n\n- `-e`, `--environments`\n  - The Octopus Environment(s) to scope variables to\n  - Separated by a space\n  - Applied to all variables\n  - e.g. `-e RC-Green RC-Blue`\n- `--vaultUri`\n  - The Vault API URI\n- `--vaultRole`\n  - The Role ID the app will run as\n- `--secret`\n  - The Vault Secret ID associated with the Vault Role\n- `--mountPoint`\n  - The Vault mount point for the secrets engine\n  - Uses the default Vault mount if not present\n- `-p`. `--prefix`\n  - A Prefix to prepend to variables\n  - Generally only used for environment variables\n\n**Note**: If the json file has any secrets and one of the parameters for Vault is not present, the tool will fail.\n\n#### Targeting a Library\n\nTargeting a library has additional arguments\n\n- `-l`, `--library`\n  - The Octopus Library to upload variables to\n- `r`, `--roles`\n  - A list of Octopus roles to scope variables to\n  - Not required\n\n##### Uploading as Json replacement variables\n\n```bash\nupload-library -f \"C:\\QA\\appsettings.json\" --library \"API Config\" -e QA \\\n-r api-role -a \"API-KEY\" -o https://octodeploy/api \\\n--merge --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n--variableType JsonConversion\n```\n\n##### Uploading as Environment Variables\n\n```bash\nupload-library -f \"C:\\QA\\appsettings.json\" -l \"API Config\" -e QA \\\n-r api-role -a \"API-KEY\" -o https://octodeploy/api \\\n--prefix \"API_\" --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n--variableType JsonConversion --roles api-role web-role\n```\n\n##### Uploading as Concatenated Environment Variables\n\nThis option creates all the environment variables as normal, but concatenates them into a comma-separated list. This list is then uploaded into one variable that is always marked `secret`\nThis variable name is hard-coded in the tool as `ConcatEnvironmentVars`.\n\nThis command is designed for deploying to Helm since it can be challenging/impossible to get a combined list of environment variables in an Octo deployment exported into the release. This makes it easier since you only need to reference once variable in Octopus to get all of your configuration.\n\nExample:\n\n```bash\nupload-library -f \"C:\\QA\\appsettings.json\" -l \"Test-Var-Set\" -e QA \\\n-r api-role -a \"API-KEY\" -o https://octodeploy/api \\\n-p \"API_\" --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n--variableType EnvironmentGlob\n```\n\n#### Clearing a Library Variable Set\n\nThis option deletes **ALL** the variables in the specified set, leaving it existing, but empty.\n\nYou need to give a value for the `-f` flag but it is ignored.\n\nExample:\n\n```bash\nclear-library -l \"Test-Var-Set\" -a \"API-KEY\" -o https://octodeploy/api -f \"\"\n```\n\n#### Targeting a Tenant\n\nThis command takes the variables from the json file and creates project variable templates in the specified project.\nIt then takes those created/existing templates and matches with the variable values and uploads them to the specified Tenant.\nTenant variables do not support scoping to Octopus roles so that option is not provided here.\nYou can scope Tenant variables to an Environment, and the tool will match them correctly, but if the Tenant is not linked to a specified environment for the specified project then it will fail.\nVariables that are not secret are created with a default value of `PLACEHOLDER_VALUE`.\nVariables that are secret are given no default value.\n\nTargeting a Tenant has two additional arguments\n\n- `-t`, `--tenant`\n  - The Octopus tenant to attach variables to\n- `-p`, `--project`\n  - The Octopus project to match Tenant variables with\n\nExample:\n\n```bash\nupload-project --tenant \"QA Infra\" --project \"Deploy API\" --variableType Environment \\\n-a \"API-KEY\" -p \"API_\" --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n-f \"C:\\QA\\appsettings.json\" -e QA RC\n```\n\n#### Targeting a Project Template\n\nThis command takes the variables from the json file and creates project variable templates in the specified project.\nVariables that are not secret are created using their values in the json file as the default value.\nVariables that are secret are given no default value.\n\nTargeting a project has one additional argument\n\n- `-p`, `--project`\n  - The Octopus project to match Tenant variables with\n\nTargeting a project also has one optional argument\n\n- `-c`, `--clear`\n  - Clears the previous template before uploading new template\n\nExample:\n\n```bash\nupload-project-template --project \"Deploy API\" --variableType JsonConversion \\\n-a \"API-KEY\" -p \"API_\" --vaultUri \"http://vaultapi:8200\" \\\n--vaultRole \"VAULT_PROVIDED_ROLE_GUID\" --secret \"VAULT_PROVIDED_ROLE_SECRET_GUID\" \\\n-f \"C:\\QA\\appsettings.json\" ---clear\n```\n\n\n#### Clearing a Project of Variable Templates\n\nDeletes **ALL** the variables templates in the specified project\n\n```bash\nclear-project --project \"Deploy API\" -o https://octodeploy/api -a \"API-KEY\"\n```\n\n#### Clearing a Tenants Variables\n\nDeletes **ALL** the variables in the specified tenant\n\n```bash\nclear-tenant --tenant \"PreProduction\" -o https://octodeploy/api -a \"API-KEY\"\n```\n\n### Cake Addin\n\nThe cake addin property names match the name and meaning of parameters for the dotnet tool. Refer to them for details.\n\n#### Cake Library Targets\n\n```csharp\n#addin \"nuget:?package=OctoLib.Core\u0026version=0.3.1\"\n#addin \"nuget:?package=Octopus.Client\u0026version=5.2.6\"\n#addin \"nuget:?package=VaultSharp\u0026version=0.11.0\"\n#addin \"nuget:?package=Microsoft.Extensions.Primitives\u0026version=2.0.0\"\n#addin \"nuget:?package=Microsoft.Extensions.DependencyInjection.Abstractions\u0026version=2.2.0\"\n#addin \"nuget:?package=Microsoft.Extensions.DependencyInjection\u0026version=2.2.0\"\nusing OctoConfig.Core;\n\nvoid UploadJson(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string library, string filePath, string prefix)\n{\n    Information($\"Uploading {filePath}\");\n    UploadLibrarySet(new LibraryTargetArgs(){\n        File = filePath,\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        Prefix = prefix,\n        VariableType = VariableType.JsonConversion\n    });\n}\n\nvoid UploadEnviro(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string library, string filePath, string prefix)\n{\n    Information($\"Uploading {filePath}\");\n    UploadLibrarySet(new LibraryTargetArgs(){\n        File = filePath,\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        Prefix = prefix,\n        VariableType = VariableType.Environment\n    });\n}\n\nvoid ValidateLibraryConfig(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string library, string filePath)\n{\n    Information($\"Validating {filePath}\");\n    ValidateConfig(new ValidateArgs(){\n        File = filePath,\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n    });\n}\n\nvoid ClearLibrary(string octoApiUri, string octoApiKey, string library)\n{\n    Information($\"Validating {filePath}\");\n    ClearLibrarySet(new ClearVariableSetArgs(){\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri\n    });\n}\n```\n\n#### Cake Tenant Targets\n\n```csharp\nvoid UploadTenantJson(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string tenant, string project, string filePath, string prefix)\n{\n    Information($\"Uploading {filePath}\");\n    UploadTenant(new TenantTargetArgs(){\n        File = filePath,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        TenantName = tenant,\n        ProjectName = project,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        VariableType = VariableType.JsonConversion\n    });\n}\n\nvoid UploadTenantEnviro(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string tenant, string project, string filePath, string prefix)\n{\n    Information($\"Uploading {filePath}\");\n    UploadTenant(new TenantTargetArgs(){\n        File = filePath,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        TenantName = tenant,\n        ProjectName = project,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        VariableType = VariableType.Environment\n    });\n}\n\nvoid ValidateTenantConfig(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string tenant, string project, string filePath)\n{\n    Information($\"Validating {filePath}\");\n    ValidateTenantConfig(new TenantTargetArgs(){\n        File = filePath,\n        TenantName = tenant,\n        ProjectName = project,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        VariableType = VariableType.Environment\n    });\n}\n\nvoid ClearTenantConfig(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string tenant, string project, string filePath)\n{\n    Information($\"Validating {filePath}\");\n    ClearTenantConfig(new TenantTargetArgs(){ ... });\n}\n\n\n```\n#### Cake Project Targets\n\n```csharp\nvoid UploadProjectJson(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string project, string filePath, string prefix, bool clear)\n{\n    Information($\"Uploading {filePath}\");\n    UploadProject(new UploadProjectArgs(){\n        File = filePath,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        ProjectName = project,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        VariableType = VariableType.JsonConversion,\n        Clear = clear\n    });\n}\n\nvoid ClearProjectConfig(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string tenant, string project, string filePath)\n{\n    Information($\"Validating {filePath}\");\n    ClearProjectConfig(new TenantTargetArgs(){ ... });\n}\n```\n#### Deprecated Cake Targets\n\n```csharp\n#addin \"nuget:?package=OctoLib.Core\u0026version=0.3.1\"\n#addin \"nuget:?package=Octopus.Client\u0026version=5.2.6\"\n#addin \"nuget:?package=VaultSharp\u0026version=0.11.0\"\n#addin \"nuget:?package=Microsoft.Extensions.Primitives\u0026version=2.0.0\"\n#addin \"nuget:?package=Microsoft.Extensions.DependencyInjection.Abstractions\u0026version=2.2.0\"\n#addin \"nuget:?package=Microsoft.Extensions.DependencyInjection\u0026version=2.2.0\"\nusing OctoConfig.Core;\n\nvoid UploadEnviro(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string library, string filePath, string prefix)\n{\n    Information($\"Uploading {filePath}\");\n    UploadEnvironmentVariables(new EnvironmentVarArgs(){\n        File = filePath,\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n        Prefix = prefix\n    });\n}\n\nvoid UploadJson(string octoApiUri, string octoApiKey, string vaultUri, string vaultRoleId, string vaultSecretId,\n    List\u003cstring\u003e enviros, List\u003cstring\u003e roles, string library, string filePath)\n{\n    Information($\"Uploading {filePath}\");\n    UploadJson(new JsonReplacementArgs(){\n        File = filePath,\n        Library = library,\n        ApiKey = octoApiKey,\n        OctoUri = octoApiUri,\n        Environments = enviros,\n        OctoRoles =  roles,\n        VaultUri = vaultUri,\n        VaultRoleId = vaultRoleId,\n        VaultSecretId = vaultSecretId,\n    });\n}\n```\n\n## Secrets\n\nSecrets are identified by starting them with `#{` and ending with `}`. In between them is an identifier for the secret and secret provider. The format of this identifier can vary based on the [secret provider](#secret-providers).\nFor example, the config file could contain the following `#{RC/RedisConnectionString}`.\nThis tells the tool to use Vault and then identifier is a URI path to the secret, so it calls out to this URL `https://vaultapi:8200/v1/secret/RC/RedisConnectionString` for the secret.\n\nSecrets are uploaded to Octopus as `Sensitive` so they are still stored securely and cannot be read.\n\nThe tool does not write or update secrets to any of the supported providers.\n\n### Secret Providers\n\nThe tool supports specifying what secret provider a secret is stored in. All providers use this format for specification:\n\n`#{\u003cProviderId\u003e:\u003cSecretIdentifier\u003e}`\n\nSo a Vault V1 secret would look like this:\n\n`#{VaultKVV1:QA/API/ConnectionString}`\n\nIf no provider is specified then it will default to using Vault Key-Value V1.\n\n#### Vault Key/Value V1\n\n[Vault KV V2](https://www.vaultproject.io/docs/secrets/kv/kv-v1.html) engine.\nThe provider ID is `VaultKVV1`\n\nSo a Vault V1 secret would look like this:\n\n`#{VaultKVV1:QA/API/ConnectionString}` or `#{QA/API/ConnectionString}`\n\nThe secret itself is expected to be the first and only thing at that path. And the json version should look like the following:\n\n```json\n{\n  \"value\":\"SECRET_HERE\",\n}\n```\n\nThese are accessed by the tool as a dictionary that just grabs the first key/value pair and only uses the value.\nOther secrets at the location will be ignored.\n\n#### Vault Key/Value V2\n\n[Vault KV V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2.html) engine.\n\nThe provider ID is `VaultKVV2`\n\nSo a Vault V1 secret would look like this:\n\n`#{VaultKVV2:QA/API/ConnectionString}`\n\nThe secret itself is expected to be the first and only thing at that path. And the json version should look like the following:\n\n```json\n\"data\" : {\n    \"value\":\"SECRET_HERE\",\n}\n```\n\nThese are accessed by the tool as a dictionary that just grabs the first key/value pair and only uses the value.\nOther secrets at the location will be ignored.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhylandsoftware%2Foctoconfigtool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhylandsoftware%2Foctoconfigtool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhylandsoftware%2Foctoconfigtool/lists"}