0
# Cloud Platform Integration
1
2
Spring Boot Admin Client provides specialized support for cloud platforms, with automatic detection and configuration optimizations for Cloud Foundry and other cloud environments.
3
4
## Cloud Foundry Integration
5
6
### CloudFoundryApplicationProperties
7
8
```java { .api }
9
@ConfigurationProperties("spring.boot.admin.client.instance.metadata")
10
public class CloudFoundryApplicationProperties {
11
// Cloud Foundry specific configuration properties
12
// Automatically populated from VCAP_APPLICATION environment variable
13
}
14
```
15
16
### CloudFoundryApplicationFactory
17
18
```java { .api }
19
public class CloudFoundryApplicationFactory implements ApplicationFactory {
20
public CloudFoundryApplicationFactory(
21
InstanceProperties instance,
22
ManagementServerProperties management,
23
ServerProperties server,
24
PathMappedEndpoints pathMappedEndpoints,
25
WebEndpointProperties webEndpoint,
26
MetadataContributor metadataContributor,
27
CloudFoundryApplicationProperties cfApplicationProperties
28
);
29
30
@Override
31
public Application createApplication();
32
}
33
```
34
35
### CloudFoundryMetadataContributor
36
37
```java { .api }
38
public class CloudFoundryMetadataContributor implements MetadataContributor {
39
public CloudFoundryMetadataContributor(CloudFoundryApplicationProperties properties);
40
41
@Override
42
public Map<String, String> getMetadata();
43
}
44
```
45
46
## Automatic Cloud Detection
47
48
The client automatically detects cloud platform environments and adjusts behavior accordingly:
49
50
### Cloud Platform Detection
51
52
```java { .api }
53
// CloudPlatform enum from Spring Boot
54
public enum CloudPlatform {
55
CLOUD_FOUNDRY,
56
HEROKU,
57
SAP,
58
KUBERNETES
59
}
60
61
// Auto-deregistration logic
62
public boolean isAutoDeregistration(Environment environment) {
63
return (this.autoDeregistration != null) ? this.autoDeregistration
64
: (CloudPlatform.getActive(environment) != null);
65
}
66
```
67
68
## Cloud Foundry Configuration
69
70
### Automatic Configuration
71
72
When running on Cloud Foundry, the client automatically:
73
74
- Detects the platform using `VCAP_APPLICATION` environment variable
75
- Configures auto-deregistration (enabled by default)
76
- Extracts application metadata from Cloud Foundry environment
77
- Sets appropriate service URLs based on Cloud Foundry routing
78
79
### Cloud Foundry Metadata
80
81
The Cloud Foundry integration automatically contributes metadata from the `VCAP_APPLICATION` environment variable:
82
83
```json
84
{
85
"cf.application.id": "12345678-1234-1234-1234-123456789012",
86
"cf.application.name": "my-app",
87
"cf.space.id": "87654321-4321-4321-4321-210987654321",
88
"cf.space.name": "production",
89
"cf.organization.id": "11111111-1111-1111-1111-111111111111",
90
"cf.organization.name": "my-org",
91
"cf.instance.index": "0",
92
"cf.instance.port": "8080"
93
}
94
```
95
96
### Cloud Foundry URL Configuration
97
98
```properties
99
# Cloud Foundry apps typically don't need explicit URL configuration
100
# The client auto-detects from CF environment variables
101
102
# But you can override if needed:
103
spring.boot.admin.client.instance.service-url=${vcap.application.uris[0]:http://localhost:8080}
104
```
105
106
## Kubernetes Integration
107
108
### Kubernetes Metadata Contributor
109
110
```java
111
@Component
112
@ConditionalOnProperty(value = "spring.boot.admin.client.kubernetes.enabled", havingValue = "true")
113
public class KubernetesMetadataContributor implements MetadataContributor {
114
115
@Override
116
public Map<String, String> getMetadata() {
117
Map<String, String> metadata = new HashMap<>();
118
119
// Read from Kubernetes Downward API environment variables
120
addIfPresent(metadata, "k8s.namespace", "KUBERNETES_NAMESPACE");
121
addIfPresent(metadata, "k8s.pod.name", "HOSTNAME");
122
addIfPresent(metadata, "k8s.pod.ip", "POD_IP");
123
addIfPresent(metadata, "k8s.node.name", "NODE_NAME");
124
addIfPresent(metadata, "k8s.service.account", "SERVICE_ACCOUNT");
125
126
return metadata;
127
}
128
129
private void addIfPresent(Map<String, String> metadata, String key, String envVar) {
130
String value = System.getenv(envVar);
131
if (value != null && !value.isEmpty()) {
132
metadata.put(key, value);
133
}
134
}
135
}
136
```
137
138
### Kubernetes Configuration
139
140
```yaml
141
# Enable Kubernetes metadata
142
spring:
143
boot:
144
admin:
145
client:
146
kubernetes:
147
enabled: true
148
149
# In Kubernetes deployment, expose pod info via Downward API
150
apiVersion: apps/v1
151
kind: Deployment
152
metadata:
153
name: my-app
154
spec:
155
template:
156
spec:
157
containers:
158
- name: my-app
159
env:
160
- name: KUBERNETES_NAMESPACE
161
valueFrom:
162
fieldRef:
163
fieldPath: metadata.namespace
164
- name: POD_IP
165
valueFrom:
166
fieldRef:
167
fieldPath: status.podIP
168
- name: NODE_NAME
169
valueFrom:
170
fieldRef:
171
fieldPath: spec.nodeName
172
```
173
174
## AWS Integration
175
176
### AWS Metadata Contributor
177
178
```java
179
@Component
180
@ConditionalOnProperty(value = "spring.boot.admin.client.aws.enabled", havingValue = "true")
181
public class AwsMetadataContributor implements MetadataContributor {
182
183
private final RestTemplate restTemplate = new RestTemplate();
184
185
@Override
186
public Map<String, String> getMetadata() {
187
Map<String, String> metadata = new HashMap<>();
188
189
try {
190
// AWS Instance Metadata Service v2
191
String token = getImdsToken();
192
if (token != null) {
193
addAwsMetadata(metadata, token);
194
}
195
} catch (Exception e) {
196
// Running outside AWS or IMDS not available
197
logger.debug("Could not retrieve AWS metadata", e);
198
}
199
200
return metadata;
201
}
202
203
private String getImdsToken() {
204
HttpHeaders headers = new HttpHeaders();
205
headers.set("X-aws-ec2-metadata-token-ttl-seconds", "21600");
206
207
HttpEntity<String> entity = new HttpEntity<>("", headers);
208
ResponseEntity<String> response = restTemplate.exchange(
209
"http://169.254.169.254/latest/api/token",
210
HttpMethod.PUT, entity, String.class);
211
212
return response.getBody();
213
}
214
215
private void addAwsMetadata(Map<String, String> metadata, String token) {
216
HttpHeaders headers = new HttpHeaders();
217
headers.set("X-aws-ec2-metadata-token", token);
218
HttpEntity<String> entity = new HttpEntity<>("", headers);
219
220
// Instance metadata
221
metadata.put("aws.instance.id", getMetadata(entity, "instance-id"));
222
metadata.put("aws.instance.type", getMetadata(entity, "instance-type"));
223
metadata.put("aws.region", getMetadata(entity, "placement/region"));
224
metadata.put("aws.availability-zone", getMetadata(entity, "placement/availability-zone"));
225
}
226
227
private String getMetadata(HttpEntity<String> entity, String path) {
228
try {
229
ResponseEntity<String> response = restTemplate.exchange(
230
"http://169.254.169.254/latest/meta-data/" + path,
231
HttpMethod.GET, entity, String.class);
232
return response.getBody();
233
} catch (Exception e) {
234
return "unknown";
235
}
236
}
237
}
238
```
239
240
## Docker Integration
241
242
### Docker Metadata Contributor
243
244
```java
245
@Component
246
@ConditionalOnProperty(value = "spring.boot.admin.client.docker.enabled", havingValue = "true")
247
public class DockerMetadataContributor implements MetadataContributor {
248
249
@Override
250
public Map<String, String> getMetadata() {
251
Map<String, String> metadata = new HashMap<>();
252
253
// Docker environment variables (if available)
254
addIfPresent(metadata, "docker.container.id", "HOSTNAME");
255
addIfPresent(metadata, "docker.image", "DOCKER_IMAGE");
256
addIfPresent(metadata, "docker.tag", "DOCKER_TAG");
257
258
// Try to detect if running in Docker
259
if (isRunningInDocker()) {
260
metadata.put("docker.container", "true");
261
}
262
263
return metadata;
264
}
265
266
private boolean isRunningInDocker() {
267
try {
268
return Files.exists(Paths.get("/.dockerenv")) ||
269
Files.lines(Paths.get("/proc/1/cgroup"))
270
.anyMatch(line -> line.contains("docker"));
271
} catch (Exception e) {
272
return false;
273
}
274
}
275
276
private void addIfPresent(Map<String, String> metadata, String key, String envVar) {
277
String value = System.getenv(envVar);
278
if (value != null && !value.isEmpty()) {
279
metadata.put(key, value);
280
}
281
}
282
}
283
```
284
285
## Configuration Examples
286
287
### Multi-Cloud Configuration
288
289
```yaml
290
spring:
291
boot:
292
admin:
293
client:
294
# Enable cloud-specific features
295
kubernetes:
296
enabled: true
297
aws:
298
enabled: true
299
docker:
300
enabled: true
301
instance:
302
metadata:
303
# Static metadata
304
deployment-type: cloud
305
monitoring-level: enhanced
306
```
307
308
### Cloud-Specific Profiles
309
310
```properties
311
# application-cloud.properties
312
spring.boot.admin.client.auto-deregistration=true
313
spring.boot.admin.client.period=30000
314
spring.boot.admin.client.instance.metadata.deployment=cloud
315
316
# application-local.properties
317
spring.boot.admin.client.auto-deregistration=false
318
spring.boot.admin.client.instance.metadata.deployment=local
319
```
320
321
## Cloud Platform Best Practices
322
323
### URL Configuration
324
- Use environment-specific URLs for different cloud deployments
325
- Leverage cloud platform service discovery when available
326
- Configure load balancer or ingress URLs for external access
327
328
### Security
329
- Use cloud platform identity and access management
330
- Secure admin server endpoints with cloud-native authentication
331
- Consider network policies and security groups
332
333
### Monitoring
334
- Leverage cloud platform monitoring integration
335
- Configure appropriate health check intervals for cloud deployments
336
- Use cloud platform logging aggregation
337
338
### Auto-scaling
339
- Configure appropriate registration periods for auto-scaling scenarios
340
- Consider the impact of rapid instance creation/destruction
341
- Use cloud platform service discovery for dynamic environments