configuration

In the process of software development, the configuration file is indispensable. We generally use it to configure some database information, interface domain name, other service interface domain name and key information. Taking the server as an example, our configuration file format is INI

Project A [Database configuration, Dependent Service (A Service) configuration]

[PROD]
dbHost = "prod.example.com:3306"
dbName = "prod_example"
dbUser = "prod"
dbPwd = "prodpwd"
serverA_Domain = "prod.a.example.com"
[TEST]
dbHost = "test.example.com:3306"
dbName = "test_example"
dbUser = "test"
dbPwd = "testpwd"
serverA_Domain = "test.a.example.com"
Copy the code

B Project [Dependent Service (SERVICE A) Configuration]

[PROD]
service_a_domain = "prod.a.example.com"
[TEST]
service_a_domain = "test.a.example.com"
Copy the code

In general, we have a test environment, we have a formal environment, and in some cases, there may be a customer who needs us to deploy the whole package independently, so we have a custom environment, which I’ll talk about later.

In the past, we used to maintain the conf.ini file by each developer and submit it together with the code. This development mode existed for a long time, but many problems occurred during this period, as follows:

  1. The developer wrote the configuration wrong,prod.example.com:3306As aprod.examples.com:3306
  2. Configure redundancy,AA service is a basic service, aboveA.BBoth projects are dependent, so a configuration is written for each project
  3. The dependencies between the configuration and the project are not documented, and if you were a spec, you might have a document,AThe items the service depends on areA.BProject, not a standard, is unlikely to be all by memory, remember to tell the truth I already don’t believe his memory, this thing if after half a year, you still can remember, I can only say that the cow force, but if the developer left, transition time forgot to handover, so this time have been buried in a pit, now we service to migrate, the domain name under the specification, Related services are modified, and service is usedservice.example.comThe domain name,AService toa.service.example.comThat’s when things go wrong
  4. After the configuration is updated, topushUse the following code to redeploy the project
  5. This is mainly for the front end, if the configuration information is written to the project, then pressF12You can find the domain name configuration information for other environments, which I don’t like to share with others (our test environment is also deployed on the Extranet).

plan

Is it possible to keep the configuration as a service independently of the project, where only the description of the configuration information is kept in the project, and the specific configuration value is maintained by each developer in the configuration service, and the relevant project directly references the configuration and automatically records the dependencies between the configuration and the project? The configuration updates automatically deploy dependent projects, so the above example looks like this

Project A [Database configuration, Dependent Service (A Service) configuration]

projecta:
  - dbHost
  - dbName
  - dbUser
  - dbPwd
serviceA:
  - domain
Copy the code

B Project [Dependent Service (SERVICE A) Configuration]

serviceA:
  - domain
Copy the code

Isn’t it much simpler?

Q: This is just a description file, how to get the value of the configuration? Student: Establish references?

A: Let’s add a “project” to describe the current project, and a “branch” to describe the configuration of the branch (i.e., the test branch, the test branch, and the master or tag for the formal environment). ItemFormat specifies the format of the file to be exported and how itemFormat handles the configuration name (for example, item A has A domain and item B has A domain).

Project A [Database configuration, Dependent Service (A Service) configuration]

format: ini
itemFormat: Splice with commas
project:
  name: ${CI_PROJECT_NAME}
  description: ${CI_PROJECT_TITLE}
  id: ${CI_PROJECT_ID}
branch: ${CI_COMMIT_REF_NAME}
configs:
    projecta:
      - dbHost
      - dbName
      - dbUser
      - dbPwd
    serviceA:
      - domain
Copy the code

B Project [Dependent Service (SERVICE A) Configuration]

format: ini
itemFormat: Splice with commas
project:
  name: ${CI_PROJECT_NAME}
  description: ${CI_PROJECT_TITLE}
  id: ${CI_PROJECT_ID}
branch: ${CI_COMMIT_REF_NAME}
configs:
    serviceA:
      - domain
Copy the code

Let’s say the configuration service is called $GITLAB_CONFIG_SERVER. Let’s do this in CI/CD, redirect the service output to the project configuration file, and then deploy or create a Docker image.

curl "$GITLAB_CONFIG_SERVER" --fd "`cat .config.yml`" > conf/app.conf
Copy the code

The $GITLAB_CONFIG_SERVER does two things

  1. The value is returned based on the configuration description
  2. Document the configuration and project dependencies

Configured to use

Web.config. Sh file

#! /bin/bash
config="
format: ini
project:
  name: ${CI_PROJECT_NAME}
  description: ${CI_PROJECT_TITLE}
  id: ${CI_PROJECT_ID}
itemFormat: project_without_dot
configs:
  projecta:
      - dbHost
      - dbName
      - dbUser
      - dbPwd
  serviceA:
      - domain
branch: ${CI_COMMIT_REF_NAME}
"
curl "${GITLAB_CONFIG_SERVER}" -fd "$config"
Copy the code

Note: Why am I using.config.sh here and not.config.yml? When using.config.yml, we often copy files of other projects, and then directly change the information under the configs, but forget to change the project information, which causes the dependency confusion, so we change the configuration description when using shell. You only need to change the information under the configs, the rest of the information can be read from the Gitlab environment variables

.gitlab-ci.yml

image: docker:git
stages:
  - build
  - deploy

build_test:
  stage: build
  image: Golang: 1.13
  script:
    - chmod a+x .config.sh
    - ./.config.sh $CI_PROJECT_NAME main.go. $CI_PROJECT_NAME  artifacts:
    expire_in: 2 days
    paths:
      - $CI_PROJECT_NAME
      - conf
  only:
    - test

deploy_test:
  stage: deploy
  image: sebble/deploy
  script:
    - The deployment code
  only:
    - test
Copy the code

Configuring the service Background

Configuration management

The blue area shows the projects that depend on this configuration

The green area shows the values configured in different branches (environments)

It may take several configurations to be edited at a time. If each edit is done automatically, it is too frequent. Therefore, a temporary save is made and all configurations are edited and then click save in the red area

The project is not configured at the beginning, select the project, click Add configuration, enter the format description.

Configuration editing and deletion are available only to users above the GitLab project MaintainerAccess level. Other users can only view the configuration. If you want a project configuration, click export configuration and paste the configuration to your.config.sh file. Never write by hand, in case you make a mistake.

Log management

Did a simple log management, edit, delete will record the log


Configure service item link, welcome star:

The service side

The front end

The full text after