Features

This guide describes how Microconfig can help you solve common microservice configuration problems.

More details you can find in Docs.

Simple Configuration Layout

Problem

Other configuration frameworks can demand a specific configuration folder structure or specific filenames.

Solution

Microconfig only asks you to create folders for your services somewhere in components folder. You choose the names and folder structure. If you have different types of configuration just place them in the same service folder.


                        components
                        ├── payments
                        │   ├── payment-backend
                        │   │   ├── application.yaml
                        │   │   └── values.deploy
                        │   └── payment-frontend
                        │       ├── application.yaml
                        │       └── values.deploy
                        └── ...
                        ...
                    

Reuse Common Parts

Problem

Microservices have a lot of shared configuration parts that is copy-pasted between them. So you need to go through all services one by one to update this shared part.

Solution

Microconfig allows you to extract common parts of configuration to a dedicated component and reuse it with #include. This way service config is more focused on unique parts and all common parts are just included. In this case if you need to update your common part you just do it in one place and everyone gets this update via #include.

payment-backend

                                        
                                        name: payment-backend

                                        server:
                                          port: 8080
                                          context: /api

                                        monitoring:
                                          secure: false
                                          base-path: /monitoring
                                          endpoints: info, health, ready, prometheus

                                        logging:
                                          level:
                                            ROOT: INFO
                                            APP: DEBUG
                                        
                                    

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          host: http://payment-backend.local
                                          path: /api

                                        monitoring:
                                          secure: true
                                          base-path: /monitoring
                                          endpoints: info, health, ready, prometheus

                                        logging:
                                          level:
                                            ROOT: INFO
                                            APP: DEBUG
                                        
                                    

payment-backend

                                        
                                        name: payment-backend

                                        server:
                                          port: 8080
                                          context: /api

                                        #include monitoring, logging
                                        
                                    

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          host: http://payment-backend.local
                                          path: /api

                                        #include monitoring, logging

                                        monitoring:
                                          secure: true
                                        
                                    

monitoring

                                        
                                        monitoring:
                                          secure: false
                                          base-path: /monitoring
                                          endpoints: info, health, ready, prometheus
                                        
                                    

logging

                                        
                                        logging:
                                          level:
                                            ROOT: INFO
                                            APP: DEBUG
                                        
                                    

Reference Values

Problem

Different services can depend on each other's configuration keys. For example frontend needs backend's api base path. You can just keep this value in two places but in this case you need to remember about this dependency and update them both.

Solution

Microconfig can reference a value from current or another component with a ${placeholder}. This allows you to keep values only in original services and all who depend on them can just have an explicit reference. In this case you need to update the value only once.

payment-backend

                                        
                                        name: payment-backend

                                        server:
                                          port: 8080
                                          context: /api

                                        ...
                                        
                                    

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          host: http://payment-backend.local
                                          path: ${payment-backend@server.context}

                                        ...
                                        
                                    

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          host: http://payment-backend.local
                                          path: /api

                                        ...
                                        
                                    

Dynamic Values

Problem

Sometimes static values are not enough, and you want to do a +1 or base64. Some values even are more readable as expressions.

Solution

Microconfig has #{'expression' + 'language'} to dynamically generate your values. It supports math operations and much more.

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          timeoutMs: 180000

                                        log:
                                          filename: PAYMENT-FRONTEND.log

                                        ...
                                        
                                    

payment-frontend

                                        
                                        name: payment-frontend

                                        payment-backend:
                                          timeoutMs: #{ 3 * 60 * 1000 }

                                        log:
                                          filename: #{ '${this@name}'.toUpperCase() }.log

                                        ...
                                        
                                    

Environment Specific Config

Problem

We deploy services to different environments that have specific properties. Your production database has different ip address than your dev. All of those specifications should be applied to final version for your environment.

Solution

Microconfig supports specific values for each environment you need. You just create an override .env. file near your base configuration. In this file you specify all that you want for your env and it will be merged with your base configuration. More specific values will override base ones.

payment-backend dev

                                        
                                        name: payment-backend

                                        payment-gateway: http://gateway-mock.local

                                        database:
                                          type: Postgres
                                          pool-size: 10
                                          url: jdbc:postgres://10.10.10.10:5432/database

                                        ...
                                        
                                    

payment-backend prod

                                        
                                        name: payment-backend

                                        payment-gateway: https://payment-gateway.com

                                        database:
                                          type: Postgres
                                          pool-size: 50
                                          url: jdbc:postgres://20.20.20.20:5432/database

                                        ...
                                        
                                    

payment-backend/application.dev.yaml

                                        
                                        payment-gateway: http://gateway-mock.local

                                        database:
                                          host: 10.10.10.10
                                        
                                    

payment-backend/application.prod.yaml

                                        
                                        payment-gateway: https://payment-gateway.com

                                        database:
                                          host: 20.20.20.20
                                          pool-size: 50
                                        
                                    

payment-backend/application.yaml

                                        
                                        name: payment-backend

                                        database:
                                          type: Postgres
                                          pool-size: 10
                                          url: jdbc:postgres://${this@database.host}:5432/database
                                        
                                    

Static Files Templating

Problem

Your services usually require some additional 3rd party configuration files like a log configuration or a deploy script. It's easy if these files don't have difference for every service but what if you need to change them a bit for each service or environment?

Solution

Microconfig can use static templates and populate them with data unique for each service via placeholders and Moustache. So you can keep your template in one place and then generate specific result for each service.

payment-backend log config dev

                                        
                                        <configuration>
                                          <appender class="FileAppender">
                                            <file>logs/payment-backend.log</file>
                                            <encoder>
                                              <pattern>%d{HH:mm:ss} %-5level %logger %msg %n</pattern>
                                            </encoder>
                                          </appender>
                                        </configuration>
                                        
                                    

payment-backend log config prod

                                        
                                        <configuration>
                                          <appender class="FileAppender">
                                            <file>logs/payment-backend.log</file>
                                            <encoder>
                                              <pattern>%d{HH:mm:ss} %-5level %logger %msg %n</pattern>
                                            </encoder>
                                          </appender>

                                          <appender class="LogstashTcpSocketAppender">
                                            <destination>30.30.30.30:9600</destination>
                                            <encoder class="LogstashEncoder">
                                              <customFields>{"servicename":"payment-backend"}</customFields>
                                            </encoder>
                                          </appender>
                                        </configuration>
                                        
                                    

log template.xml

                                        
                                        <configuration>
                                          <appender class="FileAppender">
                                            <file>logs/${this@name}.log</file>
                                            <encoder>
                                              <pattern>%d{HH:mm:ss} %-5level %logger %msg %n</pattern>
                                            </encoder>
                                          </appender>

                                        {{#appender.stash}}
                                          <appender class="LogstashTcpSocketAppender">
                                            <destination>30.30.30.30:9600</destination>
                                            <encoder class="LogstashEncoder">
                                              <customFields>{"servicename":"${this@name}"}</customFields>
                                            </encoder>
                                          </appender>
                                        {{/appender.stash}}
                                        </configuration>
                                        
                                    

payment-backend prod

                                        
                                        mc.mustache.log:
                                          fromFile: ${log@configDir}/template.xml
                                          toFile: logback.xml

                                        name: payment-backend

                                        #var appender.stash: true
                                        ...
                                        
                                    

Config Diff

Problem

When you have your configuration in some kind of templating engine it might be difficult to keep track of changes or compare different versions of configuration. For example, before new deployment to production you want to know what has been changed in your configuration.

Solution

Microconfig allows you to generate git style diff and see how your configuration changes overtime or compare different versions.

payment-frontend v1

                                        
                                        name: payment-frontend

                                        monitoring:
                                          base-path: /monitoring
                                          endpoints: info, health, ready, prometheus

                                        payment-backend:
                                          host: http://payment-backend.local
                                          path: /api

                                        server:
                                          maxThreads: 100
                                          minThreads: 10
                                          port: 80
                                          timeoutMs: 180000
                                        
                                    

payment-frontend v2

                                        
                                        name: payment-frontend

                                        monitoring:
                                          base-path: /monitoring
                                          endpoints: info, health, ready, prometheus

                                        payment-backend:
                                          host: https://payment-backend.local
                                          path: /api
                                          timeoutMs: 180000

                                        server:
                                          port: 80
                                        
                                    

payment-frontend diff between v1 and v2

                                        
                                        +payment-backend:
                                          timeoutMs: 180000

                                        -server:
                                          maxThreads: 100
                                          minThreads: 10
                                          timeoutMs: 180000

                                        payment-backend:
                                          host: http://payment-backend.local -> https://payment-backend.local
                                        
                                    

Can't wait to try it out? Head over to Quickstart