Application Config – Options and when to use

What to avoid

  • Having a variation of an application for each environment. A single artifact should be built once and then deployed to all environments otherwise you can’t guarantee that each variation has been tested.
  • Having to re-build and re-deploy the artifact if changes are required in it’s environmental configuration, for same reason as above.
  • Have secrets mixed in with your non-secret environment config (or anywhere in source code for that matter).

Consider Separation of Concerns

Consider who is going to make changes to the config, both secret and non secret.

Roles

RoleWhat
DevelopersTestersResponsible for the schema of the configuration:Need to know the keys NOT the values across environments 
OperationsSecurityResponsible for the life cycle of the configuration e.g.CRUDRenew expiring secretsEnsure securityNeed to set the values as they are the ones who create these for each environment

Where to Store

The 12 factor app says you should have config separate from application source code. Mixing environment config in with the application source code presents some problems:

  • Infrastructure team have to modify application source code to update values (or pass values to Developers)
  • Resource names are potentially sensitive information that might help a hacker to gain access to systems
  • Infrastructure would need to modify multiple app configs if those apps are deployed to a single service e.g. K8s cluster. Whereas if config is obtained by the service runtime this only has to be done once
StorageWhatRole
Configuration StoreStores environment specific values for the application but does not contain sensitive informationDoes not require encryptionAccess by general operations
Secret StoreSensitive configuration valuesConnection stringsCertificatesAccess tokensEach application should have it’s own scopeAccess restricted to elevated operational roles

Consider how config changes get into production

By accessing the config at runtime you avoid having to rebuild and redeploy app when config changes

TechniqueRequired to make config change live
Config store accessed at runtime e.g. Azure App Configuration accessed by SDKApp picks up while running  
Config store accessed at build timee.g. Config file in with source code.A file for each environment e.g. appsettings.json, appsettings-dev.json, appsettings-test.jsonRebuild and redeploy the app  
Config store accessed at deploy time e.g. HelmRedeploy the app  

Why use config store?

  • Allows config to be centrally stored so easier to debug problems and compare config across related services
  • Supports hierarchies of config parameters
  • Control feature availability in real-time through feature flags

Slow CICD Pipeline? Try These Techniques

Running buddies

Identify the long running stages that don’t need to run sequentially. For example you may run static code analysers, a Sonar code quality scan and also a Checkmarx cxSAST security scan. These can be run independently and so are good candidates to run at the same time. They also tend to take a few minutes which is generally longer than most other build tasks.

Azure Pipelines allows stages to be run in parallel by simply not specifying a dependsOn to indicate dependent jobs

jobs:
- job: Windows
  pool:
    vmImage: 'vs2017-win2016'
  steps:
  - script: echo hello from Windows
- job: macOS
  pool:
    vmImage: 'macOS-10.14'
  steps:
  - script: echo hello from macOS
- job: Linux
  pool:
    vmImage: 'ubuntu-16.04'
  steps:
  - script: echo hello from Linux

https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml

Quick feature builds, Full Pull Request builds

Rather than run all your build tasks for all branches including feature branches, think about moving longer running tasks to only execute on pull request builds. For example you could move the Sonar code quality scan to only run when merging to master through a pull request. The downside to this is that developers are getting the feedback slightly later in the cycle but one way to mitigate this is to run SonarLint within your IDE to get feedback as you code. https://www.sonarqube.org/sonarlint/

Cache

Downloading dependencies can be bandwidth intensive and time consuming. By caching the third party packages that are needed for your build you can avoid the cost of downloading each time. This is especially important if you use disposable agents that are thrown away after executing their build stage.

Azure Pipelines also supports caching across multiple pipeline runs.

https://docs.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops

Call my Agent

Check how many agents you have available to run pipeline tasks. If you are running tasks in parallel you will need multiple agents per pipeline. Check the queued tasks and consider increasing the number of available agents if you see tasks are waiting for others to complete.