2898 lines
134 KiB
HTML
2898 lines
134 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="generator" content="Asciidoctor 1.5.8">
|
|
<title>Spring Cloud Config</title>
|
|
<link rel="stylesheet" href="css/spring.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
|
|
<style>
|
|
.hidden {
|
|
display: none;
|
|
}
|
|
|
|
.switch {
|
|
border-width: 1px 1px 0 1px;
|
|
border-style: solid;
|
|
border-color: #7a2518;
|
|
display: inline-block;
|
|
}
|
|
|
|
.switch--item {
|
|
padding: 10px;
|
|
background-color: #ffffff;
|
|
color: #7a2518;
|
|
display: inline-block;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.switch--item:not(:first-child) {
|
|
border-width: 0 0 0 1px;
|
|
border-style: solid;
|
|
border-color: #7a2518;
|
|
}
|
|
|
|
.switch--item.selected {
|
|
background-color: #7a2519;
|
|
color: #ffffff;
|
|
}
|
|
</style>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
|
|
<script type="text/javascript">
|
|
function addBlockSwitches() {
|
|
$('.primary').each(function() {
|
|
primary = $(this);
|
|
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
|
|
primary.children('.title').remove();
|
|
});
|
|
$('.secondary').each(function(idx, node) {
|
|
secondary = $(node);
|
|
primary = findPrimary(secondary);
|
|
switchItem = createSwitchItem(secondary, primary.children('.switch'));
|
|
switchItem.content.addClass('hidden');
|
|
findPrimary(secondary).append(switchItem.content);
|
|
secondary.remove();
|
|
});
|
|
}
|
|
|
|
function createBlockSwitch(primary) {
|
|
blockSwitch = $('<div class="switch"></div>');
|
|
primary.prepend(blockSwitch);
|
|
return blockSwitch;
|
|
}
|
|
|
|
function findPrimary(secondary) {
|
|
candidate = secondary.prev();
|
|
while (!candidate.is('.primary')) {
|
|
candidate = candidate.prev();
|
|
}
|
|
return candidate;
|
|
}
|
|
|
|
function createSwitchItem(block, blockSwitch) {
|
|
blockName = block.children('.title').text();
|
|
content = block.children('.content').first().append(block.next('.colist'));
|
|
item = $('<div class="switch--item">' + blockName + '</div>');
|
|
item.on('click', '', content, function(e) {
|
|
$(this).addClass('selected');
|
|
$(this).siblings().removeClass('selected');
|
|
e.data.siblings('.content').addClass('hidden');
|
|
e.data.removeClass('hidden');
|
|
});
|
|
blockSwitch.append(item);
|
|
return {'item': item, 'content': content};
|
|
}
|
|
|
|
$(addBlockSwitches);
|
|
</script>
|
|
|
|
</head>
|
|
<body class="book toc2 toc-left">
|
|
<div id="header">
|
|
<h1>Spring Cloud Config</h1>
|
|
<div id="toc" class="toc2">
|
|
<div id="toctitle">Table of Contents</div>
|
|
<ul class="sectlevel1">
|
|
<li><a href="#_quick_start">Quick Start</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#_client_side_usage">Client Side Usage</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#_spring_cloud_config_server">Spring Cloud Config Server</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#_environment_repository">Environment Repository</a></li>
|
|
<li><a href="#_health_indicator">Health Indicator</a></li>
|
|
<li><a href="#_security">Security</a></li>
|
|
<li><a href="#_encryption_and_decryption">Encryption and Decryption</a></li>
|
|
<li><a href="#_key_management">Key Management</a></li>
|
|
<li><a href="#_creating_a_key_store_for_testing">Creating a Key Store for Testing</a></li>
|
|
<li><a href="#_using_multiple_keys_and_key_rotation">Using Multiple Keys and Key Rotation</a></li>
|
|
<li><a href="#_serving_encrypted_properties">Serving Encrypted Properties</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#_serving_alternative_formats">Serving Alternative Formats</a></li>
|
|
<li><a href="#_serving_plain_text">Serving Plain Text</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#spring-cloud-config-serving-plain-text-git-svn-native-backends">Git, SVN, and Native Backends</a></li>
|
|
<li><a href="#spring-cloud-config-serving-plain-text-aws-s3">AWS S3</a></li>
|
|
<li><a href="#_decrypting_plain_text">Decrypting Plain Text</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#_embedding_the_config_server">Embedding the Config Server</a></li>
|
|
<li><a href="#_push_notifications_and_spring_cloud_bus">Push Notifications and Spring Cloud Bus</a></li>
|
|
<li><a href="#_spring_cloud_config_client">Spring Cloud Config Client</a>
|
|
<ul class="sectlevel2">
|
|
<li><a href="#config-first-bootstrap">Config First Bootstrap</a></li>
|
|
<li><a href="#discovery-first-bootstrap">Discovery First Bootstrap</a></li>
|
|
<li><a href="#config-client-fail-fast">Config Client Fail Fast</a></li>
|
|
<li><a href="#config-client-retry">Config Client Retry</a></li>
|
|
<li><a href="#_locating_remote_configuration_resources">Locating Remote Configuration Resources</a></li>
|
|
<li><a href="#_specifying_multiple_urls_for_the_config_server">Specifying Multiple Urls for the Config Server</a></li>
|
|
<li><a href="#_configuring_timeouts">Configuring Timeouts</a></li>
|
|
<li><a href="#_security_2">Security</a></li>
|
|
<li><a href="#_nested_keys_in_vault">Nested Keys In Vault</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<div id="preamble">
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p><strong>2.2.2.RELEASE</strong></p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config provides server-side and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments.
|
|
The concepts on both client and server map identically to the Spring <code>Environment</code> and <code>PropertySource</code> abstractions, so they fit very well with Spring applications but can be used with any application running in any language.
|
|
As an application moves through the deployment pipeline from dev to test and into production, you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate.
|
|
The default implementation of the server storage backend uses git, so it easily supports labelled versions of configuration environments as well as being accessible to a wide range of tooling for managing the content.
|
|
It is easy to add alternative implementations and plug them in with Spring configuration.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_quick_start"><a class="link" href="#_quick_start">Quick Start</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>This quick start walks through using both the server and the client of Spring Cloud Config Server.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>First, start the server, as follows:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ cd spring-cloud-config-server
|
|
$ ../mvnw spring-boot:run</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The server is a Spring Boot application, so you can run it from your IDE if you prefer to do so (the main class is <code>ConfigServerApplication</code>).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Next try out a client, as follows:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ curl localhost:8888/foo/development
|
|
{"name":"foo","label":"master","propertySources":[
|
|
{"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
|
|
{"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
|
|
]}</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The default strategy for locating property sources is to clone a git repository (at <code>spring.cloud.config.server.git.uri</code>) and use it to initialize a mini <code>SpringApplication</code>.
|
|
The mini-application’s <code>Environment</code> is used to enumerate property sources and publish them at a JSON endpoint.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The HTTP service has resources in the following form:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>/{application}/{profile}[/{label}]
|
|
/{application}-{profile}.yml
|
|
/{label}/{application}-{profile}.yml
|
|
/{application}-{profile}.properties
|
|
/{label}/{application}-{profile}.properties</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>where <code>application</code> is injected as the <code>spring.config.name</code> in the <code>SpringApplication</code> (what is normally <code>application</code> in a regular Spring Boot app), <code>profile</code> is an active profile (or comma-separated list of properties), and <code>label</code> is an optional git label (defaults to <code>master</code>.)</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server pulls configuration for remote clients from various sources. The following example gets configuration from a git repository (which must be provided), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Other sources are any JDBC compatible database, Subversion, Hashicorp Vault, Credhub and local filesystems.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_client_side_usage"><a class="link" href="#_client_side_usage">Client Side Usage</a></h3>
|
|
<div class="paragraph">
|
|
<p>To use these features in an application, you can build it as a Spring Boot application that depends on spring-cloud-config-client (for an example, see the test cases for the config-client or the sample application).
|
|
The most convenient way to add the dependency is with a Spring Boot starter <code>org.springframework.cloud:spring-cloud-starter-config</code>.
|
|
There is also a parent pom and BOM (<code>spring-cloud-starter-parent</code>) for Maven users and a Spring IO version management properties file for Gradle and Spring CLI users. The following example shows a typical Maven configuration:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">pom.xml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"> <parent>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-parent</artifactId>
|
|
<version>{spring-boot-docs-version}</version>
|
|
<relativePath /> <!-- lookup parent from repository -->
|
|
</parent>
|
|
|
|
<dependencyManagement>
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-dependencies</artifactId>
|
|
<version>{spring-cloud-version}</version>
|
|
<type>pom</type>
|
|
<scope>import</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
</dependencyManagement>
|
|
|
|
<dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.cloud</groupId>
|
|
<artifactId>spring-cloud-starter-config</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-test</artifactId>
|
|
<scope>test</scope>
|
|
</dependency>
|
|
</dependencies>
|
|
|
|
<build>
|
|
<plugins>
|
|
<plugin>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
</plugin>
|
|
</plugins>
|
|
</build>
|
|
|
|
<!-- repositories also needed for snapshots and milestones --></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Now you can create a standard Spring Boot application, such as the following HTTP server:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>@SpringBootApplication
|
|
@RestController
|
|
public class Application {
|
|
|
|
@RequestMapping("/")
|
|
public String home() {
|
|
return "Hello World!";
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(Application.class, args);
|
|
}
|
|
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When this HTTP server runs, it picks up the external configuration from the default local config server (if it is running) on port 8888.
|
|
To modify the startup behavior, you can change the location of the config server by using <code>bootstrap.properties</code> (similar to <code>application.properties</code> but for the bootstrap phase of an application context), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>spring.cloud.config.uri: http://myconfigserver.com</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>By default, if no application name is set, <code>application</code> will be used. To modify the name, the following property can be added to the <code>bootstrap.properties</code> file:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>spring.application.name: myapp</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When setting the property <code>${spring.application.name}</code> do not prefix your app name with the reserved word <code>application-</code> to prevent issues resolving the correct property source.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The bootstrap properties show up in the <code>/env</code> endpoint as a high-priority property source, as shown in the following example.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ curl localhost:8080/env
|
|
{
|
|
"profiles":[],
|
|
"configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
|
|
"servletContextInitParams":{},
|
|
"systemProperties":{...},
|
|
...
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>A property source called <code>configService:<URL of remote repository>/<file name></code> contains the <code>foo</code> property with a value of <code>bar</code> and is the highest priority.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The URL in the property source name is the git repository, not the config server URL.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_spring_cloud_config_server"><a class="link" href="#_spring_cloud_config_server">Spring Cloud Config Server</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server provides an HTTP resource-based API for external configuration (name-value pairs or equivalent YAML content).
|
|
The server is embeddable in a Spring Boot application, by using the <code>@EnableConfigServer</code> annotation.
|
|
Consequently, the following application is a config server:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">ConfigServer.java</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@SpringBootApplication
|
|
@EnableConfigServer
|
|
public class ConfigServer {
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(ConfigServer.class, args);
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Like all Spring Boot applications, it runs on port 8080 by default, but you can switch it to the more conventional port 8888 in various ways.
|
|
The easiest, which also sets a default configuration repository, is by launching it with <code>spring.config.name=configserver</code> (there is a <code>configserver.yml</code> in the Config Server jar).
|
|
Another is to use your own <code>application.properties</code>, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">application.properties</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-properties hljs" data-lang="properties">server.port: 8888
|
|
spring.cloud.config.server.git.uri: file://${user.home}/config-repo</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>where <code>${user.home}/config-repo</code> is a git repository containing YAML and properties files.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
On Windows, you need an extra "/" in the file URL if it is absolute with a drive prefix (for example,<code><a href="file:///${user.home}/config-repo" class="bare">file:///${user.home}/config-repo</a></code>).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
<div class="paragraph">
|
|
<p>The following listing shows a recipe for creating the git repository in the preceding example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ cd $HOME
|
|
$ mkdir config-repo
|
|
$ cd config-repo
|
|
$ git init .
|
|
$ echo info.foo: bar > application.properties
|
|
$ git add -A .
|
|
$ git commit -m "Add application.properties"</pre>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
Using the local filesystem for your git repository is intended for testing only.
|
|
You should use a server to host your configuration repositories in production.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
The initial clone of your configuration repository can be quick and efficient if you keep only text files in it.
|
|
If you store binary files, especially large ones, you may experience delays on the first request for configuration or encounter out of memory errors in the server.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_environment_repository"><a class="link" href="#_environment_repository">Environment Repository</a></h3>
|
|
<div class="paragraph">
|
|
<p>Where should you store the configuration data for the Config Server?
|
|
The strategy that governs this behaviour is the <code>EnvironmentRepository</code>, serving <code>Environment</code> objects.
|
|
This <code>Environment</code> is a shallow copy of the domain from the Spring <code>Environment</code> (including <code>propertySources</code> as the main feature).
|
|
The <code>Environment</code> resources are parametrized by three variables:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><code>{application}</code>, which maps to <code>spring.application.name</code> on the client side.</p>
|
|
</li>
|
|
<li>
|
|
<p><code>{profile}</code>, which maps to <code>spring.profiles.active</code> on the client (comma-separated list).</p>
|
|
</li>
|
|
<li>
|
|
<p><code>{label}</code>, which is a server side feature labelling a "versioned" set of config files.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Repository implementations generally behave like a Spring Boot application, loading configuration files from a <code>spring.config.name</code> equal to the <code>{application}</code> parameter, and <code>spring.profiles.active</code> equal to the <code>{profiles}</code> parameter.
|
|
Precedence rules for profiles are also the same as in a regular Spring Boot application: Active profiles take precedence over defaults, and, if there are multiple profiles, the last one wins (similar to adding entries to a <code>Map</code>).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following sample client application has this bootstrap configuration:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
application:
|
|
name: foo
|
|
profiles:
|
|
active: dev,mysql</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>(As usual with a Spring Boot application, these properties could also be set by environment variables or command line arguments).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If the repository is file-based, the server creates an
|
|
<code>Environment</code> from <code>application.yml</code> (shared between all clients) and
|
|
<code>foo.yml</code> (with <code>foo.yml</code> taking precedence).
|
|
If the YAML files have documents inside them that point to Spring profiles, those are applied with higher precedence (in order of the profiles listed).
|
|
If there are profile-specific YAML (or properties) files, these are also applied with higher precedence than the defaults.
|
|
Higher precedence translates to a <code>PropertySource</code> listed earlier in the <code>Environment</code>.
|
|
(These same rules apply in a standalone Spring Boot application.)</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can set spring.cloud.config.server.accept-empty to false so that Server would return a HTTP 404 status, if the application is not found.By default, this flag is set to true.</p>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_git_backend"><a class="link" href="#_git_backend">Git Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>The default implementation of <code>EnvironmentRepository</code> uses a Git backend, which is very convenient for managing upgrades and physical environments and for auditing changes.
|
|
To change the location of the repository, you can set the <code>spring.cloud.config.server.git.uri</code> configuration property in the Config Server (for example in <code>application.yml</code>).
|
|
If you set it with a <code>file:</code> prefix, it should work from a local repository so that you can get started quickly and easily without a server. However, in that case, the server operates directly on the local repository without cloning it (it does not matter if it is not bare because the Config Server never makes changes to the "remote" repository).
|
|
To scale the Config Server up and make it highly available, you need to have all instances of the server pointing to the same repository, so only a shared file system would work.
|
|
Even in that case, it is better to use the <code>ssh:</code> protocol for a shared filesystem repository, so that the server can clone it and use a local working copy as a cache.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This repository implementation maps the <code>{label}</code> parameter of the HTTP resource to a git label (commit id, branch name, or tag).
|
|
If the git branch or tag name contains a slash (<code>/</code>), then the label in the HTTP URL should instead be specified with the special string <code>(_)</code> (to avoid ambiguity with other URL paths).
|
|
For example, if the label is <code>foo/bar</code>, replacing the slash would result in the following label: <code>foo(_)bar</code>.
|
|
The inclusion of the special string <code>(_)</code> can also be applied to the <code>{application}</code> parameter.
|
|
If you use a command-line client such as curl, be careful with the brackets in the URL — you should escape them from the shell with single quotes ('').</p>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_skipping_ssl_certificate_validation"><a class="link" href="#_skipping_ssl_certificate_validation">Skipping SSL Certificate Validation</a></h5>
|
|
<div class="paragraph">
|
|
<p>The configuration server’s validation of the Git server’s SSL certificate can be disabled by setting the <code>git.skipSslValidation</code> property to <code>true</code> (default is <code>false</code>).</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://example.com/my/repo
|
|
skipSslValidation: true</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_setting_http_connection_timeout"><a class="link" href="#_setting_http_connection_timeout">Setting HTTP Connection Timeout</a></h5>
|
|
<div class="paragraph">
|
|
<p>You can configure the time, in seconds, that the configuration server will wait to acquire an HTTP connection. Use the <code>git.timeout</code> property.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://example.com/my/repo
|
|
timeout: 4</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_placeholders_in_git_uri"><a class="link" href="#_placeholders_in_git_uri">Placeholders in Git URI</a></h5>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server supports a git repository URL with placeholders for the <code>{application}</code> and <code>{profile}</code> (and <code>{label}</code> if you need it, but remember that the label is applied as a git label anyway).
|
|
So you can support a “one repository per application” policy by using a structure similar to the following:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/myorg/{application}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can also support a “one repository per profile” policy by using a similar pattern but with
|
|
<code>{profile}</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Additionally, using the special string "(_)" within your <code>{application}</code> parameters can enable support for multiple
|
|
organizations, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/{application}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>where <code>{application}</code> is provided at request time in the following format: <code>organization(_)application</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_pattern_matching_and_multiple_repositories"><a class="link" href="#_pattern_matching_and_multiple_repositories">Pattern Matching and Multiple Repositories</a></h5>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config also includes support for more complex requirements with pattern
|
|
matching on the application and profile name.
|
|
The pattern format is a comma-separated list of <code>{application}/{profile}</code> names with wildcards (note that a pattern beginning with a wildcard may need to be quoted), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
repos:
|
|
simple: https://github.com/simple/config-repo
|
|
special:
|
|
pattern: special*/dev*,*special*/dev*
|
|
uri: https://github.com/special/config-repo
|
|
local:
|
|
pattern: local*
|
|
uri: file:/home/configsvc/config-repo</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If <code>{application}/{profile}</code> does not match any of the patterns, it uses the default URI defined under <code>spring.cloud.config.server.git.uri</code>.
|
|
In the above example, for the “simple” repository, the pattern is <code>simple/*</code> (it only matches one application named <code>simple</code> in all profiles). The “local” repository matches all application names beginning with <code>local</code> in all profiles (the <code>/*</code> suffix is added automatically to any pattern that does not have a profile matcher).</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The “one-liner” short cut used in the “simple” example can be used only if the only property to be set is the URI.
|
|
If you need to set anything else (credentials, pattern, and so on) you need to use the full form.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>pattern</code> property in the repo is actually an array, so you can use a YAML array (or <code>[0]</code>, <code>[1]</code>, etc. suffixes in properties files) to bind to multiple patterns.
|
|
You may need to do so if you are going to run apps with multiple profiles, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
repos:
|
|
development:
|
|
pattern:
|
|
- '*/development'
|
|
- '*/staging'
|
|
uri: https://github.com/development/config-repo
|
|
staging:
|
|
pattern:
|
|
- '*/qa'
|
|
- '*/production'
|
|
uri: https://github.com/staging/config-repo</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
Spring Cloud guesses that a pattern containing a profile that does not end in <code>*</code> implies that you actually want to match a list of profiles starting with this pattern (so <code>*/staging</code> is a shortcut for <code>["*/staging", "*/staging,*"]</code>, and so on).
|
|
This is common where, for instance, you need to run applications in the “development” profile locally but also the “cloud” profile remotely.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Every repository can also optionally store config files in sub-directories, and patterns to search for those directories can be specified as <code>searchPaths</code>.
|
|
The following example shows a config file at the top level:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
searchPaths: foo,bar*</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In the preceding example, the server searches for config files in the top level and in the <code>foo/</code> sub-directory and also any sub-directory whose name begins with <code>bar</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>By default, the server clones remote repositories when configuration
|
|
is first requested.
|
|
The server can be configured to clone the repositories at startup, as shown in the following top-level example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://git/common/config-repo.git
|
|
repos:
|
|
team-a:
|
|
pattern: team-a-*
|
|
cloneOnStart: true
|
|
uri: https://git/team-a/config-repo.git
|
|
team-b:
|
|
pattern: team-b-*
|
|
cloneOnStart: false
|
|
uri: https://git/team-b/config-repo.git
|
|
team-c:
|
|
pattern: team-c-*
|
|
uri: https://git/team-a/config-repo.git</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In the preceding example, the server clones team-a’s config-repo on startup, before it
|
|
accepts any requests.
|
|
All other repositories are not cloned until configuration from the repository is requested.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
Setting a repository to be cloned when the Config Server starts up can help to identify a misconfigured configuration source (such as an invalid repository URI) quickly, while the Config Server is starting up.
|
|
With <code>cloneOnStart</code> not enabled for a configuration source, the Config Server may start successfully with a misconfigured or invalid configuration source and not detect an error until an application requests configuration from that configuration source.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_authentication"><a class="link" href="#_authentication">Authentication</a></h5>
|
|
<div class="paragraph">
|
|
<p>To use HTTP basic authentication on the remote repository, add the <code>username</code> and <code>password</code> properties separately (not in the URL), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
username: trolley
|
|
password: strongpassword</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you do not use HTTPS and user credentials, SSH should also work out of the box when you store keys in the default directories (<code>~/.ssh</code>) and the URI points to an SSH location, such as <code>git@github.com:configuration/cloud-configuration</code>.
|
|
It is important that an entry for the Git server be present in the <code>~/.ssh/known_hosts</code> file and that it is in <code>ssh-rsa</code> format.
|
|
Other formats (such as <code>ecdsa-sha2-nistp256</code>) are not supported.
|
|
To avoid surprises, you should ensure that only one entry is present in the <code>known_hosts</code> file for the Git server and that it matches the URL you provided to the config server.
|
|
If you use a hostname in the URL, you want to have exactly that (not the IP) in the <code>known_hosts</code> file.
|
|
The repository is accessed by using JGit, so any documentation you find on that should be applicable.
|
|
HTTPS proxy settings can be set in <code>~/.git/config</code> or (in the same way as for any other JVM process) with
|
|
system properties (<code>-Dhttps.proxyHost</code> and <code>-Dhttps.proxyPort</code>).</p>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you do not know where your <code>~/.git</code> directory is, use <code>git config --global</code> to manipulate the settings (for example, <code>git config --global http.sslVerify false</code>).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>JGit requires RSA keys in PEM format. Below is an example ssh-keygen (from openssh) command that will generate a key in the corect format:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">ssh-keygen -m PEM -t rsa -b 4096 -f ~/config_server_deploy_key.rsa</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Warning: When working with SSH keys, the expected ssh private-key must begin with <code><code>-----BEGIN RSA PRIVATE KEY-----</code></code>. If the key starts with <code><code>-----BEGIN OPENSSH PRIVATE KEY-----</code></code> then the RSA key will not load when spring-cloud-config server is started. The error looks like:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code>- Error in object 'spring.cloud.config.server.git': codes [PrivateKeyIsValid.spring.cloud.config.server.git,PrivateKeyIsValid]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.cloud.config.server.git.,]; arguments []; default message []]; default message [Property 'spring.cloud.config.server.git.privateKey' is not a valid private key]</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To correct the above error the RSA key must be converted to PEM format. An example using openssh is provided above for generating a new key in the appropriate format.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_authentication_with_aws_codecommit"><a class="link" href="#_authentication_with_aws_codecommit">Authentication with AWS CodeCommit</a></h5>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server also supports <a href="https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html">AWS CodeCommit</a> authentication.
|
|
AWS CodeCommit uses an authentication helper when using Git from the command line.
|
|
This helper is not used with the JGit library, so a JGit CredentialProvider for AWS CodeCommit is created if the Git URI matches the AWS CodeCommit pattern.
|
|
AWS CodeCommit URIs follow this pattern://git-codecommit.${AWS_REGION}.amazonaws.com/${repopath}.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you provide a username and password with an AWS CodeCommit URI, they must be the <a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html">AWS accessKeyId and secretAccessKey</a> that provide access to the repository.
|
|
If you do not specify a username and password, the accessKeyId and secretAccessKey are retrieved by using the <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html">AWS Default Credential Provider Chain</a>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If your Git URI matches the CodeCommit URI pattern (shown earlier), you must provide valid AWS credentials in the username and password or in one of the locations supported by the default credential provider chain.
|
|
AWS EC2 instances may use <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html">IAM Roles for EC2 Instances</a>.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The <code>aws-java-sdk-core</code> jar is an optional dependency.
|
|
If the <code>aws-java-sdk-core</code> jar is not on your classpath, the AWS Code Commit credential provider is not created, regardless of the git server URI.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_authentication_with_google_cloud_source"><a class="link" href="#_authentication_with_google_cloud_source">Authentication with Google Cloud Source</a></h5>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server also supports authenticating against <a href="https://cloud.google.com/source-repositories/">Google Cloud Source</a> repositories.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If your Git URI uses the <code>http</code> or <code>https</code> protocol and the domain name is <code>source.developers.google.com</code>, the Google Cloud Source credentials provider will be used. A Google Cloud Source repository URI has the format <code><a href="https://source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}" class="bare">https://source.developers.google.com/p/${GCP_PROJECT}/r/${REPO}</a></code>. To obtain the URI for your repository, click on "Clone" in the Google Cloud Source UI, and select "Manually generated credentials". Do not generate any credentials, simply copy the displayed URI.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The Google Cloud Source credentials provider will use Google Cloud Platform application default credentials. See <a href="https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login">Google Cloud SDK documentation</a> on how to create application default credentials for a system. This approach will work for user accounts in dev environments and for service accounts in production environments.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
<code>com.google.auth:google-auth-library-oauth2-http</code> is an optional dependency.
|
|
If the <code>google-auth-library-oauth2-http</code> jar is not on your classpath, the Google Cloud Source credential provider is not created, regardless of the git server URI.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_git_ssh_configuration_using_properties"><a class="link" href="#_git_ssh_configuration_using_properties">Git SSH configuration using properties</a></h5>
|
|
<div class="paragraph">
|
|
<p>By default, the JGit library used by Spring Cloud Config Server uses SSH configuration files such as <code>~/.ssh/known_hosts</code> and <code>/etc/ssh/ssh_config</code> when connecting to Git repositories by using an SSH URI.
|
|
In cloud environments such as Cloud Foundry, the local filesystem may be ephemeral or not easily accessible.
|
|
For those cases, SSH configuration can be set by using Java properties.
|
|
In order to activate property-based SSH configuration, the <code>spring.cloud.config.server.git.ignoreLocalSshSettings</code> property must be set to <code>true</code>, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml"> spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: git@gitserver.com:team/repo1.git
|
|
ignoreLocalSshSettings: true
|
|
hostKey: someHostKey
|
|
hostKeyAlgorithm: ssh-rsa
|
|
privateKey: |
|
|
-----BEGIN RSA PRIVATE KEY-----
|
|
MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
|
|
IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
|
|
ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
|
|
1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
|
|
oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
|
|
DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
|
|
fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
|
|
BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
|
|
EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
|
|
5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
|
|
+AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
|
|
pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
|
|
ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
|
|
xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
|
|
dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
|
|
PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
|
|
VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
|
|
FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
|
|
gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
|
|
VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
|
|
cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
|
|
KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
|
|
CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
|
|
q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
|
|
69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
|
|
-----END RSA PRIVATE KEY-----</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following table describes the SSH configuration properties.</p>
|
|
</div>
|
|
<table class="tableblock frame-all grid-all stretch">
|
|
<caption class="title">Table 1. SSH Configuration Properties</caption>
|
|
<colgroup>
|
|
<col style="width: 50%;">
|
|
<col style="width: 50%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-left valign-top">Property Name</th>
|
|
<th class="tableblock halign-left valign-top">Remarks</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>ignoreLocalSshSettings</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">If <code>true</code>, use property-based instead of file-based SSH config. Must be set at as <code>spring.cloud.config.server.git.ignoreLocalSshSettings</code>, <strong>not</strong> inside a repository definition.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>privateKey</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Valid SSH private key. Must be set if <code>ignoreLocalSshSettings</code> is true and Git URI is SSH format.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>hostKey</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Valid SSH host key. Must be set if <code>hostKeyAlgorithm</code> is also set.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>hostKeyAlgorithm</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">One of <code>ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521</code>. Must be set if <code>hostKey</code> is also set.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>strictHostKeyChecking</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code> or <code>false</code>. If false, ignore errors with host key.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>knownHostsFile</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Location of custom <code>.known_hosts</code> file.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>preferredAuthentications</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Override server authentication method order. This should allow for evading login prompts if server has keyboard-interactive authentication before the <code>publickey</code> method.</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_placeholders_in_git_search_paths"><a class="link" href="#_placeholders_in_git_search_paths">Placeholders in Git Search Paths</a></h5>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server also supports a search path with placeholders for the <code>{application}</code> and <code>{profile}</code> (and <code>{label}</code> if
|
|
you need it), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
searchPaths: '{application}'</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The preceding listing causes a search of the repository for files in the same name as the directory (as well as the top level).
|
|
Wildcards are also valid in a search path with placeholders (any matching directory is included in the search).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_force_pull_in_git_repositories"><a class="link" href="#_force_pull_in_git_repositories">Force pull in Git Repositories</a></h5>
|
|
<div class="paragraph">
|
|
<p>As mentioned earlier, Spring Cloud Config Server makes a clone of the remote git repository in case the local copy gets dirty (for example,
|
|
folder content changes by an OS process) such that Spring Cloud Config Server cannot update the local copy from remote repository.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To solve this issue, there is a <code>force-pull</code> property that makes Spring Cloud Config Server force pull from the remote repository if the local copy is dirty, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
force-pull: true</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you have a multiple-repositories configuration, you can configure the <code>force-pull</code> property per repository, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://git/common/config-repo.git
|
|
force-pull: true
|
|
repos:
|
|
team-a:
|
|
pattern: team-a-*
|
|
uri: https://git/team-a/config-repo.git
|
|
force-pull: true
|
|
team-b:
|
|
pattern: team-b-*
|
|
uri: https://git/team-b/config-repo.git
|
|
force-pull: true
|
|
team-c:
|
|
pattern: team-c-*
|
|
uri: https://git/team-a/config-repo.git</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The default value for <code>force-pull</code> property is <code>false</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_deleting_untracked_branches_in_git_repositories"><a class="link" href="#_deleting_untracked_branches_in_git_repositories">Deleting untracked branches in Git Repositories</a></h5>
|
|
<div class="paragraph">
|
|
<p>As Spring Cloud Config Server has a clone of the remote git repository
|
|
after check-outing branch to local repo (e.g fetching properties by label) it will keep this branch
|
|
forever or till the next server restart (which creates new local repo).
|
|
So there could be a case when remote branch is deleted but local copy of it is still available for fetching.
|
|
And if Spring Cloud Config Server client service starts with <code>--spring.cloud.config.label=deletedRemoteBranch,master</code>
|
|
it will fetch properties from <code>deletedRemoteBranch</code> local branch, but not from <code>master</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>In order to keep local repository branches clean and up to remote - <code>deleteUntrackedBranches</code> property could be set.
|
|
It will make Spring Cloud Config Server <strong>force</strong> delete untracked branches from local repository.
|
|
Example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
deleteUntrackedBranches: true</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The default value for <code>deleteUntrackedBranches</code> property is <code>false</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_git_refresh_rate"><a class="link" href="#_git_refresh_rate">Git Refresh Rate</a></h5>
|
|
<div class="paragraph">
|
|
<p>You can control how often the config server will fetch updated configuration data
|
|
from your Git backend by using <code>spring.cloud.config.server.git.refreshRate</code>. The
|
|
value of this property is specified in seconds. By default the value is 0, meaning
|
|
the config server will fetch updated configuration from the Git repo every time it
|
|
is requested.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_version_control_backend_filesystem_use"><a class="link" href="#_version_control_backend_filesystem_use">Version Control Backend Filesystem Use</a></h4>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
With VCS-based backends (git, svn), files are checked out or cloned to the local filesystem.
|
|
By default, they are put in the system temporary directory with a prefix of <code>config-repo-</code>.
|
|
On linux, for example, it could be <code>/tmp/config-repo-<randomid></code>.
|
|
Some operating systems <a href="https://serverfault.com/questions/377348/when-does-tmp-get-cleared/377349#377349">routinely clean out</a> temporary directories.
|
|
This can lead to unexpected behavior, such as missing properties.
|
|
To avoid this problem, change the directory that Config Server uses by setting <code>spring.cloud.config.server.git.basedir</code> or <code>spring.cloud.config.server.svn.basedir</code> to a directory that does not reside in the system temp structure.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_file_system_backend"><a class="link" href="#_file_system_backend">File System Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>There is also a “native” profile in the Config Server that does not use Git but loads the config files from the local classpath or file system (any static URL you want to point to with <code>spring.cloud.config.server.native.searchLocations</code>).
|
|
To use the native profile, launch the Config Server with <code>spring.profiles.active=native</code>.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
Remember to use the <code>file:</code> prefix for file resources (the default without a prefix is usually the classpath).
|
|
As with any Spring Boot configuration, you can embed <code>${}</code>-style environment placeholders, but remember that absolute paths in Windows require an extra <code>/</code> (for example, <code><a href="file:///${user.home}/config-repo" class="bare">file:///${user.home}/config-repo</a></code>).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock warning">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-warning" title="Warning"></i>
|
|
</td>
|
|
<td class="content">
|
|
The default value of the <code>searchLocations</code> is identical to a local Spring Boot application (that is, <code>[classpath:/, classpath:/config,
|
|
file:./, file:./config]</code>).
|
|
This does not expose the <code>application.properties</code> from the server to all clients, because any property sources present in the server are removed before being sent to the client.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
A filesystem backend is great for getting started quickly and for testing.
|
|
To use it in production, you need to be sure that the file system is reliable and shared across all instances of the Config Server.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The search locations can contain placeholders for <code>{application}</code>, <code>{profile}</code>, and <code>{label}</code>.
|
|
In this way, you can segregate the directories in the path and choose a strategy that makes sense for you (such as subdirectory per application or subdirectory per profile).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you do not use placeholders in the search locations, this repository also appends the <code>{label}</code> parameter of the HTTP resource to a suffix on the search path, so properties files are loaded from each search location <strong>and</strong> a subdirectory with the same name as the label (the labelled properties take precedence in the Spring Environment).
|
|
Thus, the default behaviour with no placeholders is the same as adding a search location ending with <code>/{label}/</code>.
|
|
For example, <code>file:/tmp/config</code> is the same as <code>file:/tmp/config,file:/tmp/config/{label}</code>.
|
|
This behavior can be disabled by setting <code>spring.cloud.config.server.native.addLabelLocations=false</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="vault-backend"><a class="link" href="#vault-backend">Vault Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server also supports <a href="https://www.vaultproject.io">Vault</a> as a backend.</p>
|
|
</div>
|
|
<div class="sidebarblock">
|
|
<div class="content">
|
|
<div class="paragraph">
|
|
<p>Vault is a tool for securely accessing secrets.
|
|
A secret is anything that to which you want to tightly control access, such as API keys, passwords, certificates, and other sensitive information. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>For more information on Vault, see the <a href="https://learn.hashicorp.com/vault/?track=getting-started#getting-started">Vault quick start guide</a>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To enable the config server to use a Vault backend, you can run your config server with the <code>vault</code> profile.
|
|
For example, in your config server’s <code>application.properties</code>, you can add <code>spring.profiles.active=vault</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>By default, the config server assumes that your Vault server runs at <code><a href="http://127.0.0.1:8200" class="bare">http://127.0.0.1:8200</a></code>.
|
|
It also assumes that the name of backend is <code>secret</code> and the key is <code>application</code>.
|
|
All of these defaults can be configured in your config server’s <code>application.properties</code>.
|
|
The following table describes configurable Vault properties:</p>
|
|
</div>
|
|
<table class="tableblock frame-all grid-all stretch">
|
|
<colgroup>
|
|
<col style="width: 50%;">
|
|
<col style="width: 50%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-left valign-top">Name</th>
|
|
<th class="tableblock halign-left valign-top">Default Value</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">127.0.0.1</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">port</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">8200</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">scheme</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">http</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">backend</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">secret</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">defaultKey</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">application</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">profileSeparator</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">,</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">kvVersion</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">skipSslValidation</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">timeout</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">namespace</p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="admonitionblock important">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-important" title="Important"></i>
|
|
</td>
|
|
<td class="content">
|
|
All of the properties in the preceding table must be prefixed with <code>spring.cloud.config.server.vault</code> or placed in the correct Vault section of a composite configuration.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>All configurable properties can be found in <code>org.springframework.cloud.config.server.environment.VaultEnvironmentProperties</code>.</p>
|
|
</div>
|
|
<div class="admonitionblock important">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-important" title="Important"></i>
|
|
</td>
|
|
<td class="content">
|
|
Vault 0.10.0 introduced a versioned key-value backend (k/v backend version 2) that exposes a different API than earlier versions, it now requires a <code>data/</code> between the mount path and the actual context path and wraps secrets in a <code>data</code> object. Setting <code>spring.cloud.config.server.vault.kv-version=2</code> will take this into account.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Optionally, there is support for the Vault Enterprise <code>X-Vault-Namespace</code> header. To have it sent to Vault set the <code>namespace</code> property.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>With your config server running, you can make HTTP requests to the server to retrieve
|
|
values from the Vault backend.
|
|
To do so, you need a token for your Vault server.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>First, place some data in you Vault, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">$ vault kv put secret/application foo=bar baz=bam
|
|
$ vault kv put secret/myapp foo=myappsbar</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Second, make an HTTP request to your config server to retrieve the values, as shown in the following example:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>$ curl -X "GET" "http://localhost:8888/myapp/default" -H "X-Config-Token: yourtoken"</code></p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You should see a response similar to the following:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">{
|
|
"name":"myapp",
|
|
"profiles":[
|
|
"default"
|
|
],
|
|
"label":null,
|
|
"version":null,
|
|
"state":null,
|
|
"propertySources":[
|
|
{
|
|
"name":"vault:myapp",
|
|
"source":{
|
|
"foo":"myappsbar"
|
|
}
|
|
},
|
|
{
|
|
"name":"vault:application",
|
|
"source":{
|
|
"baz":"bam",
|
|
"foo":"bar"
|
|
}
|
|
}
|
|
]
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The default way for a client to provide the necessary authentication to let Config Server talk to Vault is to set the X-Config-Token header.
|
|
However, you can instead omit the header and configure the authentication in the server, by setting the same configuration properties as Spring Cloud Vault.
|
|
The property to set is <code>spring.cloud.config.server.vault.authentication</code>.
|
|
It should be set to one of the supported authentication methods.
|
|
You may also need to set other properties specific to the authentication method you use, by using the same property names as documented for <code>spring.cloud.vault</code> but instead using the <code>spring.cloud.config.server.vault</code> prefix.
|
|
See the <a href="https://cloud.spring.io/spring-cloud-vault/reference/html/#vault.config.authentication">Spring Cloud Vault Reference Guide</a> for more detail.</p>
|
|
</div>
|
|
<div class="admonitionblock important">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-important" title="Important"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you omit the X-Config-Token header and use a server property to set the authentication, the Config Server application needs an additional dependency on Spring Vault to enable the additional authentication options.
|
|
See the <a href="https://docs.spring.io/spring-vault/docs/current/reference/html/#dependencies">Spring Vault Reference Guide</a> for how to add that dependency.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_multiple_properties_sources"><a class="link" href="#_multiple_properties_sources">Multiple Properties Sources</a></h5>
|
|
<div class="paragraph">
|
|
<p>When using Vault, you can provide your applications with multiple properties sources.
|
|
For example, assume you have written data to the following paths in Vault:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">secret/myApp,dev
|
|
secret/myApp
|
|
secret/application,dev
|
|
secret/application</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Properties written to <code>secret/application</code> are available to <a href="#_vault_server">all applications using the Config Server</a>.
|
|
An application with the name, <code>myApp</code>, would have any properties written to <code>secret/myApp</code> and <code>secret/application</code> available to it.
|
|
When <code>myApp</code> has the <code>dev</code> profile enabled, properties written to all of the above paths would be available to it, with properties in the first path in the list taking priority over the others.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_accessing_backends_through_a_proxy"><a class="link" href="#_accessing_backends_through_a_proxy">Accessing Backends Through a Proxy</a></h4>
|
|
<div class="paragraph">
|
|
<p>The configuration server can access a Git or Vault backend through an HTTP or HTTPS proxy. This behavior is controlled for either Git or Vault by settings under <code>proxy.http</code> and <code>proxy.https</code>. These settings are per repository, so if you are using a <a href="#composite-environment-repositories">composite environment repository</a> you must configure proxy settings for each backend in the composite individually. If using a network which requires separate proxy servers for HTTP and HTTPS URLs, you can configure both the HTTP and the HTTPS proxy settings for a single backend.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following table describes the proxy configuration properties for both HTTP and HTTPS proxies. All of these properties must be prefixed by <code>proxy.http</code> or <code>proxy.https</code>.</p>
|
|
</div>
|
|
<table class="tableblock frame-all grid-all stretch">
|
|
<caption class="title">Table 2. Proxy Configuration Properties</caption>
|
|
<colgroup>
|
|
<col style="width: 50%;">
|
|
<col style="width: 50%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-left valign-top">Property Name</th>
|
|
<th class="tableblock halign-left valign-top">Remarks</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>host</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">The host of the proxy.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>port</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">The port with which to access the proxy.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>nonProxyHosts</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Any hosts which the configuration server should access outside the proxy. If values are provided for both <code>proxy.http.nonProxyHosts</code> and <code>proxy.https.nonProxyHosts</code>, the <code>proxy.http</code> value will be used.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>username</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">The username with which to authenticate to the proxy. If values are provided for both <code>proxy.http.username</code> and <code>proxy.https.username</code>, the <code>proxy.http</code> value will be used.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>password</strong></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">The password with which to authenticate to the proxy. If values are provided for both <code>proxy.http.password</code> and <code>proxy.https.password</code>, the <code>proxy.http</code> value will be used.</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="paragraph">
|
|
<p>The following configuration uses an HTTPS proxy to access a Git repository.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: git
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: https://github.com/spring-cloud-samples/config-repo
|
|
proxy:
|
|
https:
|
|
host: my-proxy.host.io
|
|
password: myproxypassword
|
|
port: '3128'
|
|
username: myproxyusername
|
|
nonProxyHosts: example.com</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_sharing_configuration_with_all_applications"><a class="link" href="#_sharing_configuration_with_all_applications">Sharing Configuration With All Applications</a></h4>
|
|
<div class="paragraph">
|
|
<p>Sharing configuration between all applications varies according to which approach you take, as described in the following topics:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><a href="#spring-cloud-config-server-file-based-repositories">File Based Repositories</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#spring-cloud-config-server-vault-server">Vault Server</a></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="spring-cloud-config-server-file-based-repositories"><a class="link" href="#spring-cloud-config-server-file-based-repositories">File Based Repositories</a></h5>
|
|
<div class="paragraph">
|
|
<p>With file-based (git, svn, and native) repositories, resources with file names in <code>application*</code> (<code>application.properties</code>, <code>application.yml</code>, <code>application-*.properties</code>, and so on) are shared between all client applications.
|
|
You can use resources with these file names to configure global defaults and have them be overridden by application-specific files as necessary.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <a href="#property-overrides">property overrides</a> feature can also be used for setting global defaults, with placeholders applications
|
|
allowed to override them locally.</p>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
With the “native” profile (a local file system backend) , you should use an explicit search location that is not part of the server’s own configuration.
|
|
Otherwise, the <code>application*</code> resources in the default search locations get removed because they are part of the server.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="spring-cloud-config-server-vault-server"><a class="link" href="#spring-cloud-config-server-vault-server">Vault Server</a></h5>
|
|
<div class="paragraph">
|
|
<p>When using Vault as a backend, you can share configuration with all applications by placing configuration in <code>secret/application</code>.
|
|
For example, if you run the following Vault command, all applications using the config server will have the properties <code>foo</code> and <code>baz</code> available to them:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">$ vault write secret/application foo=bar baz=bam</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_credhub_server"><a class="link" href="#_credhub_server">CredHub Server</a></h5>
|
|
<div class="paragraph">
|
|
<p>When using CredHub as a backend, you can share configuration with all applications by placing configuration in <code>/application/</code> or by placing it in the <code>default</code> profile for the application.
|
|
For example, if you run the following CredHub command, all applications using the config server will have the properties <code>shared.color1</code> and <code>shared.color2</code> available to them:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">credhub set --name "/application/profile/master/shared" --type=json
|
|
value: {"shared.color1": "blue", "shared.color": "red"}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">credhub set --name "/my-app/default/master/more-shared" --type=json
|
|
value: {"shared.word1": "hello", "shared.word2": "world"}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_jdbc_backend"><a class="link" href="#_jdbc_backend">JDBC Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server supports JDBC (relational database) as a backend for configuration properties.
|
|
You can enable this feature by adding <code>spring-jdbc</code> to the classpath and using the <code>jdbc</code> profile or by adding a bean of type <code>JdbcEnvironmentRepository</code>.
|
|
If you include the right dependencies on the classpath (see the user guide for more details on that), Spring Boot configures a data source.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The database needs to have a table called <code>PROPERTIES</code> with columns called <code>APPLICATION</code>, <code>PROFILE</code>, and <code>LABEL</code> (with the usual <code>Environment</code> meaning), plus <code>KEY</code> and <code>VALUE</code> for the key and value pairs in <code>Properties</code> style.
|
|
All fields are of type String in Java, so you can make them <code>VARCHAR</code> of whatever length you need.
|
|
Property values behave in the same way as they would if they came from Spring Boot properties files named <code>{application}-{profile}.properties</code>, including all the encryption and decryption, which will be applied as post-processing steps (that is, not in the repository implementation directly).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_redis_backend"><a class="link" href="#_redis_backend">Redis Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server supports Redis as a backend for configuration properties.
|
|
You can enable this feature by adding a dependency to <a href="https://spring.io/projects/spring-data-redis">Spring Data Redis</a>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">pom.xml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
</dependency>
|
|
</dependencies></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following configuration uses Spring Data <code>RedisTemplate</code> to access a Redis. We can use <code>spring.redis.*</code> properties to override default connection settings.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: redis
|
|
redis:
|
|
host: redis
|
|
port: 16379</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The properties should be stored as fields in a hash. The name of hash should be the same as <code>spring.application.name</code> property or conjunction of <code>spring.application.name</code> and <code>spring.profiles.active[n]</code>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">HMSET sample-app server.port "8100" sample.topic.name "test" test.property1 "property1"</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>After executing the command visible above a hash should contain the following keys with values:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>HGETALL sample-app
|
|
{
|
|
"server.port": "8100",
|
|
"sample.topic.name": "test",
|
|
"test.property1": "property1"
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When no profile is specified <code>default</code> will be used.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_aws_s3_backend"><a class="link" href="#_aws_s3_backend">AWS S3 Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server supports AWS S3 as a backend for configuration properties.
|
|
You can enable this feature by adding a dependency to the <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-s3.html">AWS Java SDK For Amazon S3</a>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">pom.xml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies>
|
|
<dependency>
|
|
<groupId>com.amazonaws</groupId>
|
|
<artifactId>aws-java-sdk-s3</artifactId>
|
|
</dependency>
|
|
</dependencies></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following configuration uses the AWS S3 client to access configuration files. We can use <code>spring.awss3.*</code> properties to select the bucket where your configuration is stored.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: awss3
|
|
cloud:
|
|
config:
|
|
server:
|
|
awss3:
|
|
region: us-east-1
|
|
bucket: bucket1</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>It is also possible to specify an AWS URL to <a href="https://aws.amazon.com/blogs/developer/using-new-regions-and-endpoints/">override the standard endpoint</a> of your S3 service with <code>spring.awss3.endpoint</code>. This allows support for beta regions of S3, and other S3 compatible storage APIs.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Credentials are found using the <a href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html">Default AWS Credential Provider Chain</a>. Versioned and encrypted buckets are supported without further configuration.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Configuration files are stored in your bucket as <code>{application}-{profile}.properties</code>, <code>{application}-{profile}.yml</code> or <code>{application}-{profile}.json</code>. An optional label can be provided to specify a directory path to the file.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When no profile is specified <code>default</code> will be used.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_credhub_backend"><a class="link" href="#_credhub_backend">CredHub Backend</a></h4>
|
|
<div class="paragraph">
|
|
<p>Spring Cloud Config Server supports <a href="https://docs.cloudfoundry.org/credhub">CredHub</a> as a backend for configuration properties.
|
|
You can enable this feature by adding a dependency to <a href="https://spring.io/projects/spring-credhub">Spring CredHub</a>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">pom.xml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.credhub</groupId>
|
|
<artifactId>spring-credhub-starter</artifactId>
|
|
</dependency>
|
|
</dependencies></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following configuration uses mutual TLS to access a CredHub:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: credhub
|
|
cloud:
|
|
config:
|
|
server:
|
|
credhub:
|
|
url: https://credhub:8844</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The properties should be stored as JSON, such as:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">credhub set --name "/demo-app/default/master/toggles" --type=json
|
|
value: {"toggle.button": "blue", "toggle.link": "red"}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-sh hljs" data-lang="sh">credhub set --name "/demo-app/default/master/abs" --type=json
|
|
value: {"marketing.enabled": true, "external.enabled": false}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>All client applications with the name <code>spring.cloud.config.name=demo-app</code> will have the following properties available to them:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>{
|
|
toggle.button: "blue",
|
|
toggle.link: "red",
|
|
marketing.enabled: true,
|
|
external.enabled: false
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When no profile is specified <code>default</code> will be used and when no label is specified <code>master</code> will be used as a default value.
|
|
NOTE: Values added to <code>application</code> will be shared by all the applications.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_oauth_2_0"><a class="link" href="#_oauth_2_0">OAuth 2.0</a></h5>
|
|
<div class="paragraph">
|
|
<p>You can authenticate with <a href="https://oauth.net/2/">OAuth 2.0</a> using <a href="https://docs.cloudfoundry.org/concepts/architecture/uaa.html">UAA</a> as a provider.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">pom.xml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><dependencies>
|
|
<dependency>
|
|
<groupId>org.springframework.security</groupId>
|
|
<artifactId>spring-security-config</artifactId>
|
|
</dependency>
|
|
<dependency>
|
|
<groupId>org.springframework.security</groupId>
|
|
<artifactId>spring-security-oauth2-client</artifactId>
|
|
</dependency>
|
|
</dependencies></code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following configuration uses OAuth 2.0 and UAA to access a CredHub:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: credhub
|
|
cloud:
|
|
config:
|
|
server:
|
|
credhub:
|
|
url: https://credhub:8844
|
|
oauth2:
|
|
registration-id: credhub-client
|
|
security:
|
|
oauth2:
|
|
client:
|
|
registration:
|
|
credhub-client:
|
|
provider: uaa
|
|
client-id: credhub_config_server
|
|
client-secret: asecret
|
|
authorization-grant-type: client_credentials
|
|
provider:
|
|
uaa:
|
|
token-uri: https://uaa:8443/oauth/token</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The used UAA client-id should have <code>credhub.read</code> as scope.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="composite-environment-repositories"><a class="link" href="#composite-environment-repositories">Composite Environment Repositories</a></h4>
|
|
<div class="paragraph">
|
|
<p>In some scenarios, you may wish to pull configuration data from multiple environment repositories.
|
|
To do so, you can enable the <code>composite</code> profile in your configuration server’s application properties or YAML file.
|
|
If, for example, you want to pull configuration data from a Subversion repository as well as two Git repositories, you can set the following properties for your configuration server:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: composite
|
|
cloud:
|
|
config:
|
|
server:
|
|
composite:
|
|
-
|
|
type: svn
|
|
uri: file:///path/to/svn/repo
|
|
-
|
|
type: git
|
|
uri: file:///path/to/rex/git/repo
|
|
-
|
|
type: git
|
|
uri: file:///path/to/walter/git/repo</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Using this configuration, precedence is determined by the order in which repositories are listed under the <code>composite</code> key.
|
|
In the above example, the Subversion repository is listed first, so a value found in the Subversion repository will override values found for the same property in one of the Git repositories.
|
|
A value found in the <code>rex</code> Git repository will be used before a value found for the same property in the <code>walter</code> Git repository.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you want to pull configuration data only from repositories that are each of distinct types, you can enable the corresponding profiles, rather than the <code>composite</code> profile, in your configuration server’s application properties or YAML file.
|
|
If, for example, you want to pull configuration data from a single Git repository and a single HashiCorp Vault server, you can set the following properties for your configuration server:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
profiles:
|
|
active: git, vault
|
|
cloud:
|
|
config:
|
|
server:
|
|
git:
|
|
uri: file:///path/to/git/repo
|
|
order: 2
|
|
vault:
|
|
host: 127.0.0.1
|
|
port: 8200
|
|
order: 1</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Using this configuration, precedence can be determined by an <code>order</code> property.
|
|
You can use the <code>order</code> property to specify the priority order for all your repositories.
|
|
The lower the numerical value of the <code>order</code> property, the higher priority it has.
|
|
The priority order of a repository helps resolve any potential conflicts between repositories that contain values for the same properties.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
If your composite environment includes a Vault server as in the previous example, you must include a Vault token in every request made to the configuration server. See <a href="#vault-backend">Vault Backend</a>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
Any type of failure when retrieving values from an environment repository results in a failure for the entire composite environment.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When using a composite environment, it is important that all repositories contain the same labels.
|
|
If you have an environment similar to those in the preceding examples and you request configuration data with the <code>master</code> label but the Subversion repository does not contain a branch called <code>master</code>, the entire request fails.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="sect4">
|
|
<h5 id="_custom_composite_environment_repositories"><a class="link" href="#_custom_composite_environment_repositories">Custom Composite Environment Repositories</a></h5>
|
|
<div class="paragraph">
|
|
<p>In addition to using one of the environment repositories from Spring Cloud, you can also provide your own <code>EnvironmentRepository</code> bean to be included as part of a composite environment.
|
|
To do so, your bean must implement the <code>EnvironmentRepository</code> interface.
|
|
If you want to control the priority of your custom <code>EnvironmentRepository</code> within the composite environment, you should also implement the <code>Ordered</code> interface and override the <code>getOrdered</code> method.
|
|
If you do not implement the <code>Ordered</code> interface, your <code>EnvironmentRepository</code> is given the lowest priority.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="property-overrides"><a class="link" href="#property-overrides">Property Overrides</a></h4>
|
|
<div class="paragraph">
|
|
<p>The Config Server has an “overrides” feature that lets the operator provide configuration properties to all applications.
|
|
The overridden properties cannot be accidentally changed by the application with the normal Spring Boot hooks.
|
|
To declare overrides, add a map of name-value pairs to <code>spring.cloud.config.server.overrides</code>, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
overrides:
|
|
foo: bar</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The preceding examples causes all applications that are config clients to read <code>foo=bar</code>, independent of their own configuration.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
A configuration system cannot force an application to use configuration data in any particular way.
|
|
Consequently, overrides are not enforceable.
|
|
However, they do provide useful default behavior for Spring Cloud Config clients.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
Normally, Spring environment placeholders with <code>${}</code> can be escaped (and resolved on the client) by using backslash (<code>\</code>) to escape the <code>$</code> or the <code>{</code>.
|
|
For example, <code>\${app.foo:bar}</code> resolves to <code>bar</code>, unless the app provides its own <code>app.foo</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
In YAML, you do not need to escape the backslash itself.
|
|
However, in properties files, you do need to escape the backslash, when you configure the overrides on the server.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can change the priority of all overrides in the client to be more like default values, letting applications supply their own values in environment variables or System properties, by setting the <code>spring.cloud.config.overrideNone=true</code> flag (the default is false) in the remote repository.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_health_indicator"><a class="link" href="#_health_indicator">Health Indicator</a></h3>
|
|
<div class="paragraph">
|
|
<p>Config Server comes with a Health Indicator that checks whether the configured <code>EnvironmentRepository</code> is working.
|
|
By default, it asks the <code>EnvironmentRepository</code> for an application named <code>app</code>, the <code>default</code> profile, and the default label provided by the <code>EnvironmentRepository</code> implementation.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can configure the Health Indicator to check more applications along with custom profiles and custom labels, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
server:
|
|
health:
|
|
repositories:
|
|
myservice:
|
|
label: mylabel
|
|
myservice-dev:
|
|
name: myservice
|
|
profiles: development</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can disable the Health Indicator by setting <code>spring.cloud.config.server.health.enabled=false</code>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_security"><a class="link" href="#_security">Security</a></h3>
|
|
<div class="paragraph">
|
|
<p>You can secure your Config Server in any way that makes sense to you (from physical network security to OAuth2 bearer tokens), because Spring Security and Spring Boot offer support for many security arrangements.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To use the default Spring Boot-configured HTTP Basic security, include Spring Security on the classpath (for example, through <code>spring-boot-starter-security</code>).
|
|
The default is a username of <code>user</code> and a randomly generated password. A random password is not useful in practice, so we recommend you configure the password (by setting <code>spring.security.user.password</code>) and encrypt it (see below for instructions on how to do that).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_encryption_and_decryption"><a class="link" href="#_encryption_and_decryption">Encryption and Decryption</a></h3>
|
|
<div class="admonitionblock important">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-important" title="Important"></i>
|
|
</td>
|
|
<td class="content">
|
|
To use the encryption and decryption features you need the full-strength JCE installed in your JVM (it is not included by default).
|
|
You can download the “Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files” from Oracle and follow the installation instructions (essentially, you need to replace the two policy files in the JRE lib/security directory with the ones that you downloaded).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If the remote property sources contain encrypted content (values starting with <code>{cipher}</code>), they are decrypted before sending to clients over HTTP.
|
|
The main advantage of this setup is that the property values need not be in plain text when they are “at rest” (for example, in a git repository).
|
|
If a value cannot be decrypted, it is removed from the property source and an additional property is added with the same key but prefixed with <code>invalid</code> and a value that means “not applicable” (usually <code><n/a></code>).
|
|
This is largely to prevent cipher text being used as a password and accidentally leaking.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you set up a remote config repository for config client applications, it might contain an <code>application.yml</code> similar to the following:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">application.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
datasource:
|
|
username: dbuser
|
|
password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Encrypted values in a .properties file must not be wrapped in quotes. Otherwise, the value is not decrypted. The following example shows values that would work:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">application.properties</div>
|
|
<div class="content">
|
|
<pre>spring.datasource.username: dbuser
|
|
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can safely push this plain text to a shared git repository, and the secret password remains protected.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The server also exposes <code>/encrypt</code> and <code>/decrypt</code> endpoints (on the assumption that these are secured and only accessed by authorized agents).
|
|
If you edit a remote config file, you can use the Config Server to encrypt values by POSTing to the <code>/encrypt</code> endpoint, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ curl localhost:8888/encrypt -d mysecret
|
|
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
If the value you encrypt has characters in it that need to be URL encoded, you should use the <code>--data-urlencode</code> option to <code>curl</code> to make sure they are encoded properly.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
Be sure not to include any of the curl command statistics in the encrypted value.
|
|
Outputting the value to a file can help avoid this problem.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The inverse operation is also available through <code>/decrypt</code> (provided the server is
|
|
configured with a symmetric key or a full key pair), as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
|
|
mysecret</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you testing with curl, then use <code>--data-urlencode</code> (instead of <code>-d</code>) or set an explicit <code>Content-Type: text/plain</code> to make sure curl encodes the data correctly when there are special characters ('+' is particularly tricky).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Take the encrypted value and add the <code>{cipher}</code> prefix before you put it in the YAML or properties file and before you commit and push it to a remote (potentially insecure) store.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>/encrypt</code> and <code>/decrypt</code> endpoints also both accept paths in the form of <code>/*/{application}/{profiles}</code>, which can be used to control cryptography on a per-application (name) and per-profile basis when clients call into the main environment resource.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
To control the cryptography in this granular way, you must also provide a <code>@Bean</code> of type <code>TextEncryptorLocator</code> that creates a different encryptor per name and profiles.
|
|
The one that is provided by default does not do so (all encryptions use the same key).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>spring</code> command line client (with Spring Cloud CLI extensions
|
|
installed) can also be used to encrypt and decrypt, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ spring encrypt mysecret --key foo
|
|
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
|
|
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
|
|
mysecret</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To use a key in a file (such as an RSA public key for encryption), prepend
|
|
the key value with "@" and provide the file path, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
|
|
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The <code>--key</code> argument is mandatory (despite having a <code>--</code> prefix).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_key_management"><a class="link" href="#_key_management">Key Management</a></h3>
|
|
<div class="paragraph">
|
|
<p>The Config Server can use a symmetric (shared) key or an asymmetric one (RSA key pair).
|
|
The asymmetric choice is superior in terms of security, but it is often more convenient to use a symmetric key since it is a single property value to configure in the <code>bootstrap.properties</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To configure a symmetric key, you need to set <code>encrypt.key</code> to a secret String (or use the <code>ENCRYPT_KEY</code> environment variable to keep it out of plain-text configuration files).</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
You cannot configure an asymmetric key using <code>encrypt.key</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To configure an asymmetric key use a keystore (e.g. as
|
|
created by the <code>keytool</code> utility that comes with the JDK). The
|
|
keystore properties are <code>encrypt.keyStore.*</code> with <code>*</code> equal to</p>
|
|
</div>
|
|
<table class="tableblock frame-all grid-all stretch">
|
|
<colgroup>
|
|
<col style="width: 50%;">
|
|
<col style="width: 50%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-center valign-top">Property</th>
|
|
<th class="tableblock halign-center valign-top">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>encrypt.keyStore.location</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Contains a <code>Resource</code> location</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>encrypt.keyStore.password</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Holds the password that unlocks the keystore</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>encrypt.keyStore.alias</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Identifies which key in the store to use</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>encrypt.keyStore.type</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">The type of KeyStore to create. Defaults to <code>jks</code>.</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="paragraph">
|
|
<p>The encryption is done with the public key, and a private key is
|
|
needed for decryption.
|
|
Thus, in principle, you can configure only the public key in the server if you want to only encrypt (and are prepared to decrypt the values yourself locally with the private key).
|
|
In practice, you might not want to do decrypt locally, because it spreads the key management process around all the clients, instead of
|
|
concentrating it in the server.
|
|
On the other hand, it can be a useful option if your config server is relatively insecure and only a handful of clients need the encrypted properties.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_creating_a_key_store_for_testing"><a class="link" href="#_creating_a_key_store_for_testing">Creating a Key Store for Testing</a></h3>
|
|
<div class="paragraph">
|
|
<p>To create a keystore for testing, you can use a command resembling the following:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>$ keytool -genkeypair -alias mytestkey -keyalg RSA \
|
|
-dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
|
|
-keypass changeme -keystore server.jks -storepass letmein</pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When using JDK 11 or above you may get the following warning when using the command above. In this case
|
|
you probably want to make sure the <code>keypass</code> and <code>storepass</code> values match.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre>Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.</pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Put the <code>server.jks</code> file in the classpath (for instance) and then, in
|
|
your <code>bootstrap.yml</code>, for the Config Server, create the following settings:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">encrypt:
|
|
keyStore:
|
|
location: classpath:/server.jks
|
|
password: letmein
|
|
alias: mytestkey
|
|
secret: changeme</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_using_multiple_keys_and_key_rotation"><a class="link" href="#_using_multiple_keys_and_key_rotation">Using Multiple Keys and Key Rotation</a></h3>
|
|
<div class="paragraph">
|
|
<p>In addition to the <code>{cipher}</code> prefix in encrypted property values, the Config Server looks for zero or more <code>{name:value}</code> prefixes before the start of the (Base64 encoded) cipher text.
|
|
The keys are passed to a <code>TextEncryptorLocator</code>, which can do whatever logic it needs to locate a <code>TextEncryptor</code> for the cipher.
|
|
If you have configured a keystore (<code>encrypt.keystore.location</code>), the default locator looks for keys with aliases supplied by the <code>key</code> prefix, with a cipher text like resembling the following:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">foo:
|
|
bar: `{cipher}{key:testkey}...`</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The locator looks for a key named "testkey".
|
|
A secret can also be supplied by using a <code>{secret:…​}</code> value in the prefix.
|
|
However, if it is not supplied, the default is to use the keystore password (which is what you get when you build a keystore and do not specify a secret).
|
|
If you do supply a secret, you should also encrypt the secret using a custom <code>SecretLocator</code>.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When the keys are being used only to encrypt a few bytes of configuration data (that is, they are not being used elsewhere), key rotation is hardly ever necessary on cryptographic grounds.
|
|
However, you might occasionally need to change the keys (for example, in the event of a security breach).
|
|
In that case, all the clients would need to change their source config files (for example, in git) and use a new <code>{key:…​}</code> prefix in all the ciphers.
|
|
Note that the clients need to first check that the key alias is available in the Config Server keystore.</p>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you want to let the Config Server handle all encryption as well as decryption, the <code>{name:value}</code> prefixes can also be added as plain text posted to the <code>/encrypt</code> endpoint, .
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_serving_encrypted_properties"><a class="link" href="#_serving_encrypted_properties">Serving Encrypted Properties</a></h3>
|
|
<div class="paragraph">
|
|
<p>Sometimes you want the clients to decrypt the configuration locally, instead of doing it in the server.
|
|
In that case, if you provide the <code>encrypt.*</code> configuration to locate a key, you can still have <code>/encrypt</code> and <code>/decrypt</code> endpoints, but you need to explicitly switch off the decryption of outgoing properties by placing <code>spring.cloud.config.server.encrypt.enabled=false</code> in <code>bootstrap.[yml|properties]</code>.
|
|
If you do not care about the endpoints, it should work if you do not configure either the key or the enabled flag.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_serving_alternative_formats"><a class="link" href="#_serving_alternative_formats">Serving Alternative Formats</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The default JSON format from the environment endpoints is perfect for consumption by Spring applications, because it maps directly onto the <code>Environment</code> abstraction.
|
|
If you prefer, you can consume the same data as YAML or Java properties by adding a suffix (".yml", ".yaml" or ".properties") to the resource path.
|
|
This can be useful for consumption by applications that do not care about the structure of the JSON endpoints or the extra metadata they provide (for example, an application that is not using Spring might benefit from the simplicity of this approach).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The YAML and properties representations have an additional flag (provided as a boolean query parameter called <code>resolvePlaceholders</code>) to signal that placeholders in the source documents (in the standard Spring <code>${…​}</code> form) should be resolved in the output before rendering, where possible.
|
|
This is a useful feature for consumers that do not know about the Spring placeholder conventions.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
There are limitations in using the YAML or properties formats, mainly in relation to the loss of metadata.
|
|
For example, the JSON is structured as an ordered list of property sources, with names that correlate with the source.
|
|
The YAML and properties forms are coalesced into a single map, even if the origin of the values has multiple sources, and the names of the original source files are lost.
|
|
Also, the YAML representation is not necessarily a faithful representation of the YAML source in a backing repository either. It is constructed from a list of flat property sources, and assumptions have to be made about the form of the keys.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_serving_plain_text"><a class="link" href="#_serving_plain_text">Serving Plain Text</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Instead of using the <code>Environment</code> abstraction (or one of the alternative representations of it in YAML or properties format), your applications might need generic plain-text configuration files that are tailored to their environment.
|
|
The Config Server provides these through an additional endpoint at <code>/{application}/{profile}/{label}/{path}</code>, where <code>application</code>, <code>profile</code>, and <code>label</code> have the same meaning as the regular environment endpoint, but <code>path</code> is a path to a file name (such as <code>log.xml</code>).
|
|
The source files for this endpoint are located in the same way as for the environment endpoints.
|
|
The same search path is used for properties and YAML files.
|
|
However, instead of aggregating all matching resources, only the first one to match is returned.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>After a resource is located, placeholders in the normal format (<code>${…​}</code>) are resolved by using the effective <code>Environment</code> for the supplied application name, profile, and label.
|
|
In this way, the resource endpoint is tightly integrated with the environment endpoints.</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
As with the source files for environment configuration, the <code>profile</code> is used to resolve the file name.
|
|
So, if you want a profile-specific file, <code>/*/development/*/logback.xml</code> can be resolved by a file called <code>logback-development.xml</code> (in preference to <code>logback.xml</code>).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you do not want to supply the <code>label</code> and let the server use the default label, you can supply a <code>useDefaultLabel</code> request parameter.
|
|
Consequently, the preceding example for the <code>default</code> profile could be <code>/sample/default/nginx.conf?useDefaultLabel</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>At present, Spring Cloud Config can serve plaintext for git, SVN, native backends, and AWS S3.
|
|
The support for git, SVN, and native backends is identical. AWS S3 works a bit differently.
|
|
The following sections show how each one works:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><a href="#spring-cloud-config-serving-plain-text-git-svn-native-backends">Git, SVN, and Native Backends</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#spring-cloud-config-serving-plain-text-aws-s3">AWS S3</a></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-config-serving-plain-text-git-svn-native-backends"><a class="link" href="#spring-cloud-config-serving-plain-text-git-svn-native-backends">Git, SVN, and Native Backends</a></h3>
|
|
<div class="paragraph">
|
|
<p>Consider the following example for a GIT or SVN repository or a native backend:</p>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="content">
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code>application.yml
|
|
nginx.conf</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>nginx.conf</code> might resemble the following listing:</p>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="content">
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code>server {
|
|
listen 80;
|
|
server_name ${nginx.server.name};
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>application.yml</code> might resemble the following listing:</p>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="content">
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">nginx:
|
|
server:
|
|
name: example.com
|
|
---
|
|
spring:
|
|
profiles: development
|
|
nginx:
|
|
server:
|
|
name: develop.com</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>/sample/default/master/nginx.conf</code> resource might be as follows:</p>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="content">
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code>server {
|
|
listen 80;
|
|
server_name example.com;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>/sample/development/master/nginx.conf</code> might be as follows:</p>
|
|
</div>
|
|
<div class="exampleblock">
|
|
<div class="content">
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code>server {
|
|
listen 80;
|
|
server_name develop.com;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="spring-cloud-config-serving-plain-text-aws-s3"><a class="link" href="#spring-cloud-config-serving-plain-text-aws-s3">AWS S3</a></h3>
|
|
<div class="paragraph">
|
|
<p>To enable serving plain text for AWS s3, the Config Server application needs to include a dependency on Spring Cloud AWS.
|
|
For details on how to set up that dependency, see the
|
|
<a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.1.3.RELEASE/single/spring-cloud-aws.html#_spring_cloud_aws_maven_dependency_management">Spring Cloud AWS Reference Guide</a>.
|
|
Then you need to configure Spring Cloud AWS, as described in the
|
|
<a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.1.3.RELEASE/single/spring-cloud-aws.html#_configuring_credentials">Spring Cloud AWS Reference Guide</a>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_decrypting_plain_text"><a class="link" href="#_decrypting_plain_text">Decrypting Plain Text</a></h3>
|
|
<div class="paragraph">
|
|
<p>By default, encrypted values in plain text files are not decrypted. In order to enable decryption for plain text files, set <code>spring.cloud.config.server.encrypt.enabled=true</code> and <code>spring.cloud.config.server.encrypt.plainTextEncrypt=true</code> in <code>bootstrap.[yml|properties]</code></p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
Decrypting plain text files is only supported for YAML, JSON, and properties file extensions.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If this feature is enabled, and an unsupported file extention is requested, any encrypted values in the file will not be decrypted.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_embedding_the_config_server"><a class="link" href="#_embedding_the_config_server">Embedding the Config Server</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>The Config Server runs best as a standalone application.
|
|
However, if need be, you can embed it in another application.
|
|
To do so, use the <code>@EnableConfigServer</code> annotation.
|
|
An optional property named <code>spring.cloud.config.server.bootstrap</code> can be useful in this case.
|
|
It is a flag to indicate whether the server should configure itself from its own remote repository.
|
|
By default, the flag is off, because it can delay startup.
|
|
However, when embedded in another application, it makes sense to initialize the same way as any other application.
|
|
When setting <code>spring.cloud.config.server.bootstrap</code> to <code>true</code> you must also use a <a href="#composite-environment-repositories">composite environment repository configuration</a>.
|
|
For example</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
application:
|
|
name: configserver
|
|
profiles:
|
|
active: composite
|
|
cloud:
|
|
config:
|
|
server:
|
|
composite:
|
|
- type: native
|
|
search-locations: ${HOME}/Desktop/config
|
|
bootstrap: true</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
If you use the bootstrap flag, the config server needs to have its name and repository URI configured in <code>bootstrap.yml</code>.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>To change the location of the server endpoints, you can (optionally) set <code>spring.cloud.config.server.prefix</code> (for example, <code>/config</code>), to serve the resources under a prefix.
|
|
The prefix should start but not end with a <code>/</code>.
|
|
It is applied to the <code>@RequestMappings</code> in the Config Server (that is, underneath the Spring Boot <code>server.servletPath</code> and <code>server.contextPath</code> prefixes).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you want to read the configuration for an application directly from the backend repository (instead of from the config server), you
|
|
basically want an embedded config server with no endpoints.
|
|
You can switch off the endpoints entirely by not using the <code>@EnableConfigServer</code> annotation (set <code>spring.cloud.config.server.bootstrap=true</code>).</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_push_notifications_and_spring_cloud_bus"><a class="link" href="#_push_notifications_and_spring_cloud_bus">Push Notifications and Spring Cloud Bus</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Many source code repository providers (such as Github, Gitlab, Gitea, Gitee, Gogs, or Bitbucket) notify you of changes in a repository through a webhook.
|
|
You can configure the webhook through the provider’s user interface as a URL and a set of events in which you are interested.
|
|
For instance, <a href="https://developer.github.com/v3/activity/events/types/#pushevent">Github</a> uses a POST to the webhook with a JSON body containing a list of commits and a header (<code>X-Github-Event</code>) set to <code>push</code>.
|
|
If you add a dependency on the <code>spring-cloud-config-monitor</code> library and activate the Spring Cloud Bus in your Config Server, then a <code>/monitor</code> endpoint is enabled.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>When the webhook is activated, the Config Server sends a <code>RefreshRemoteApplicationEvent</code> targeted at the applications it thinks might have changed.
|
|
The change detection can be strategized.
|
|
However, by default, it looks for changes in files that match the application name (for example, <code>foo.properties</code> is targeted at the <code>foo</code> application, while <code>application.properties</code> is targeted at all applications).
|
|
The strategy to use when you want to override the behavior is <code>PropertyPathNotificationExtractor</code>, which accepts the request headers and body as parameters and returns a list of file paths that changed.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The default configuration works out of the box with Github, Gitlab, Gitea, Gitee, Gogs or Bitbucket.
|
|
In addition to the JSON notifications from Github, Gitlab, Gitee, or Bitbucket, you can trigger a change notification by POSTing to <code>/monitor</code> with form-encoded body parameters in the pattern of <code>path={application}</code>.
|
|
Doing so broadcasts to applications matching the <code>{application}</code> pattern (which can contain wildcards).</p>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The <code>RefreshRemoteApplicationEvent</code> is transmitted only if the <code>spring-cloud-bus</code> is activated in both the Config Server and in the client application.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
The default configuration also detects filesystem changes in local git repositories. In that case, the webhook is not used. However, as soon as you edit a config file, a refresh is broadcast.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_spring_cloud_config_client"><a class="link" href="#_spring_cloud_config_client">Spring Cloud Config Client</a></h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>A Spring Boot application can take immediate advantage of the Spring Config Server (or other external property sources provided by the application developer).
|
|
It also picks up some additional useful features related to <code>Environment</code> change events.</p>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="config-first-bootstrap"><a class="link" href="#config-first-bootstrap">Config First Bootstrap</a></h3>
|
|
<div class="paragraph">
|
|
<p>The default behavior for any application that has the Spring Cloud Config Client on the classpath is as follows:
|
|
When a config client starts, it binds to the Config Server (through the <code>spring.cloud.config.uri</code> bootstrap configuration property) and initializes Spring <code>Environment</code> with remote property sources.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The net result of this behavior is that all client applications that want to consume the Config Server need a <code>bootstrap.yml</code> (or an environment variable) with the server address set in <code>spring.cloud.config.uri</code> (it defaults to "http://localhost:8888").</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="discovery-first-bootstrap"><a class="link" href="#discovery-first-bootstrap">Discovery First Bootstrap</a></h3>
|
|
<div class="paragraph">
|
|
<p>If you use a <code>DiscoveryClient</code> implementation, such as Spring Cloud Netflix and Eureka Service Discovery or Spring Cloud Consul, you can have the Config Server register with the Discovery Service.
|
|
However, in the default “Config First” mode, clients cannot take advantage of the registration.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you prefer to use <code>DiscoveryClient</code> to locate the Config Server, you can do so by setting <code>spring.cloud.config.discovery.enabled=true</code> (the default is <code>false</code>).
|
|
The net result of doing so is that client applications all need a <code>bootstrap.yml</code> (or an environment variable) with the appropriate discovery configuration.
|
|
For example, with Spring Cloud Netflix, you need to define the Eureka server address (for example, in <code>eureka.client.serviceUrl.defaultZone</code>).
|
|
The price for using this option is an extra network round trip on startup, to locate the service registration.
|
|
The benefit is that, as long as the Discovery Service is a fixed point, the Config Server can change its coordinates.
|
|
The default service ID is <code>configserver</code>, but you can change that on the client by setting <code>spring.cloud.config.discovery.serviceId</code> (and on the server, in the usual way for a service, such as by setting <code>spring.application.name</code>).</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The discovery client implementations all support some kind of metadata map (for example, we have <code>eureka.instance.metadataMap</code> for Eureka).
|
|
Some additional properties of the Config Server may need to be configured in its service registration metadata so that clients can connect correctly.
|
|
If the Config Server is secured with HTTP Basic, you can configure the credentials as <code>user</code> and <code>password</code>.
|
|
Also, if the Config Server has a context path, you can set <code>configPath</code>.
|
|
For example, the following YAML file is for a Config Server that is a Eureka client:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">eureka:
|
|
instance:
|
|
...
|
|
metadataMap:
|
|
user: osufhalskjrtl
|
|
password: lviuhlszvaorhvlo5847
|
|
configPath: /config</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="config-client-fail-fast"><a class="link" href="#config-client-fail-fast">Config Client Fail Fast</a></h3>
|
|
<div class="paragraph">
|
|
<p>In some cases, you may want to fail startup of a service if it cannot connect to the Config Server.
|
|
If this is the desired behavior, set the bootstrap configuration property <code>spring.cloud.config.fail-fast=true</code> to make the client halt with an Exception.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="config-client-retry"><a class="link" href="#config-client-retry">Config Client Retry</a></h3>
|
|
<div class="paragraph">
|
|
<p>If you expect that the config server may occasionally be unavailable when your application starts, you can make it keep trying after a failure.
|
|
First, you need to set <code>spring.cloud.config.fail-fast=true</code>.
|
|
Then you need to add <code>spring-retry</code> and <code>spring-boot-starter-aop</code> to your classpath.
|
|
The default behavior is to retry six times with an initial backoff interval of 1000ms and an exponential multiplier of 1.1 for subsequent backoffs.
|
|
You can configure these properties (and others) by setting the <code>spring.cloud.config.retry.*</code> configuration properties.</p>
|
|
</div>
|
|
<div class="admonitionblock tip">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-tip" title="Tip"></i>
|
|
</td>
|
|
<td class="content">
|
|
To take full control of the retry behavior, add a <code>@Bean</code> of type <code>RetryOperationsInterceptor</code> with an ID of <code>configServerRetryInterceptor</code>.
|
|
Spring Retry has a <code>RetryInterceptorBuilder</code> that supports creating one.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_locating_remote_configuration_resources"><a class="link" href="#_locating_remote_configuration_resources">Locating Remote Configuration Resources</a></h3>
|
|
<div class="paragraph">
|
|
<p>The Config Service serves property sources from <code>/{application}/{profile}/{label}</code>, where the default bindings in the client app are as follows:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>"name" = <code>${spring.application.name}</code></p>
|
|
</li>
|
|
<li>
|
|
<p>"profile" = <code>${spring.profiles.active}</code> (actually <code>Environment.getActiveProfiles()</code>)</p>
|
|
</li>
|
|
<li>
|
|
<p>"label" = "master"</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
When setting the property <code>${spring.application.name}</code> do not prefix your app name with the reserved word <code>application-</code> to prevent issues resolving the correct property source.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>You can override all of them by setting <code>spring.cloud.config.*</code> (where <code>*</code> is <code>name</code>, <code>profile</code> or <code>label</code>).
|
|
The <code>label</code> is useful for rolling back to previous versions of configuration.
|
|
With the default Config Server implementation, it can be a git label, branch name, or commit ID.
|
|
Label can also be provided as a comma-separated list.
|
|
In that case, the items in the list are tried one by one until one succeeds.
|
|
This behavior can be useful when working on a feature branch.
|
|
For instance, you might want to align the config label with your branch but make it optional (in that case, use <code>spring.cloud.config.label=myfeature,develop</code>).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_specifying_multiple_urls_for_the_config_server"><a class="link" href="#_specifying_multiple_urls_for_the_config_server">Specifying Multiple Urls for the Config Server</a></h3>
|
|
<div class="paragraph">
|
|
<p>To ensure high availability when you have multiple instances of Config Server deployed and expect one or more instances to be unavailable from time to time, you can either specify multiple URLs (as a comma-separated list under the <code>spring.cloud.config.uri</code> property) or have all your instances register in a Service Registry like Eureka ( if using Discovery-First Bootstrap mode ). Note that doing so ensures high availability only when the Config Server is not running (that is, when the application has exited) or when a connection timeout has occurred. For example, if the Config Server returns a 500 (Internal Server Error) response or the Config Client receives a 401 from the Config Server (due to bad credentials or other causes), the Config Client does not try to fetch properties from other URLs. An error of that kind indicates a user issue rather than an availability problem.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you use HTTP basic security on your Config Server, it is currently possible to support per-Config Server auth credentials only if you embed the credentials in each URL you specify under the <code>spring.cloud.config.uri</code> property. If you use any other kind of security mechanism, you cannot (currently) support per-Config Server authentication and authorization.</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_configuring_timeouts"><a class="link" href="#_configuring_timeouts">Configuring Timeouts</a></h3>
|
|
<div class="paragraph">
|
|
<p>If you want to configure timeout thresholds:</p>
|
|
</div>
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p>Read timeouts can be configured by using the property <code>spring.cloud.config.request-read-timeout</code>.</p>
|
|
</li>
|
|
<li>
|
|
<p>Connection timeouts can be configured by using the property <code>spring.cloud.config.request-connect-timeout</code>.</p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_security_2"><a class="link" href="#_security_2">Security</a></h3>
|
|
<div class="paragraph">
|
|
<p>If you use HTTP Basic security on the server, clients need to know the password (and username if it is not the default).
|
|
You can specify the username and password through the config server URI or via separate username and password properties, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
uri: https://user:secret@myconfig.mycompany.com</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following example shows an alternate way to pass the same information:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
uri: https://myconfig.mycompany.com
|
|
username: user
|
|
password: secret</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The <code>spring.cloud.config.password</code> and <code>spring.cloud.config.username</code> values override anything that is provided in the URI.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you deploy your apps on Cloud Foundry, the best way to provide the password is through service credentials (such as in the URI, since it does not need to be in a config file).
|
|
The following example works locally and for a user-provided service on Cloud Foundry named <code>configserver</code>:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
uri: ${vcap.services.configserver.credentials.uri:http://user:password@localhost:8888}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>If you use another form of security, you might need to <a href="#custom-rest-template">provide a <code>RestTemplate</code></a> to the <code>ConfigServicePropertySourceLocator</code> (for example, by grabbing it in the bootstrap context and injecting it).</p>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_health_indicator_2"><a class="link" href="#_health_indicator_2">Health Indicator</a></h4>
|
|
<div class="paragraph">
|
|
<p>The Config Client supplies a Spring Boot Health Indicator that attempts to load configuration from the Config Server.
|
|
The health indicator can be disabled by setting <code>health.config.enabled=false</code>.
|
|
The response is also cached for performance reasons.
|
|
The default cache time to live is 5 minutes.
|
|
To change that value, set the <code>health.config.time-to-live</code> property (in milliseconds).</p>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="custom-rest-template"><a class="link" href="#custom-rest-template">Providing A Custom RestTemplate</a></h4>
|
|
<div class="paragraph">
|
|
<p>In some cases, you might need to customize the requests made to the config server from the client.
|
|
Typically, doing so involves passing special <code>Authorization</code> headers to authenticate requests to the server.
|
|
To provide a custom <code>RestTemplate</code>:</p>
|
|
</div>
|
|
<div class="olist arabic">
|
|
<ol class="arabic">
|
|
<li>
|
|
<p>Create a new configuration bean with an implementation of <code>PropertySourceLocator</code>, as shown in the following example:</p>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">CustomConfigServiceBootstrapConfiguration.java</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Configuration
|
|
public class CustomConfigServiceBootstrapConfiguration {
|
|
@Bean
|
|
public ConfigServicePropertySourceLocator configServicePropertySourceLocator() {
|
|
ConfigClientProperties clientProperties = configClientProperties();
|
|
ConfigServicePropertySourceLocator configServicePropertySourceLocator = new ConfigServicePropertySourceLocator(clientProperties);
|
|
configServicePropertySourceLocator.setRestTemplate(customRestTemplate(clientProperties));
|
|
return configServicePropertySourceLocator;
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="admonitionblock note">
|
|
<table>
|
|
<tr>
|
|
<td class="icon">
|
|
<i class="fa icon-note" title="Note"></i>
|
|
</td>
|
|
<td class="content">
|
|
For a simplified approach to adding <code>Authorization</code> headers, the <code>spring.cloud.config.headers.*</code> property can be used instead.
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="olist arabic">
|
|
<ol class="arabic">
|
|
<li>
|
|
<p>In <code>resources/META-INF</code>, create a file called
|
|
<code>spring.factories</code> and specify your custom configuration, as shown in the following example:</p>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">spring.factories</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-properties hljs" data-lang="properties">org.springframework.cloud.bootstrap.BootstrapConfiguration = com.my.config.client.CustomConfigServiceBootstrapConfiguration</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect3">
|
|
<h4 id="_vault"><a class="link" href="#_vault">Vault</a></h4>
|
|
<div class="paragraph">
|
|
<p>When using Vault as a backend to your config server, the client needs to supply a token for the server to retrieve values from Vault.
|
|
This token can be provided within the client by setting <code>spring.cloud.config.token</code>
|
|
in <code>bootstrap.yml</code>, as shown in the following example:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="title">bootstrap.yml</div>
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring:
|
|
cloud:
|
|
config:
|
|
token: YourVaultToken</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect2">
|
|
<h3 id="_nested_keys_in_vault"><a class="link" href="#_nested_keys_in_vault">Nested Keys In Vault</a></h3>
|
|
<div class="paragraph">
|
|
<p>Vault supports the ability to nest keys in a value stored in Vault, as shown in the following example:</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p><code>echo -n '{"appA": {"secret": "appAsecret"}, "bar": "baz"}' | vault write secret/myapp -</code></p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>This command writes a JSON object to your Vault.
|
|
To access these values in Spring, you would use the traditional dot(<code>.</code>) annotation, as shown in the following example</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Value("${appA.secret}")
|
|
String name = "World";</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The preceding code would sets the value of the <code>name</code> variable to <code>appAsecret</code>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
|
|
<script type="text/javascript" src="js/toc.js"></script>
|
|
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
|
|
<script src="js/highlight/highlight.min.js"></script>
|
|
<script>hljs.initHighlighting()</script>
|
|
</body>
|
|
</html> |