Hey! In the last lecture we covered why Vault is useful and what it can do. Today we'll get hands-on — install it, configure it, and make it work with our Spring Boot apps.
Installing Vault
The easiest way is to use Docker. One command and you'll have a working Vault:
docker run --cap-add=IPC_LOCK \
-e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' \
-p 8200:8200 \
vault
Remember the token myroot — we'll need it!
First steps with the Vault CLI
Let's get familiar with the Vault CLI. First, point to the server:
export VAULT_ADDR='http://127.0.0.1:8200'
Now log in with our token:
vault login myroot
Adding the first secrets
Vault stores secrets in special "namespaces". Let's create one for our app:
vault secrets enable -path=secret kv-v2
Now add the first secret:
vault kv put secret/myapp/database \
username=dbuser \
password=dbpass
Check that it was saved:
vault kv get secret/myapp/database
Connecting Spring Boot
Now the fun part — connect our app to Vault.
1. Add dependencies
In pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
2. Configure the app
In application.yml:
spring:
cloud:
vault:
host: localhost
port: 8200
scheme: http
authentication: TOKEN
token: myroot
kv:
enabled: true
backend: secret
default-context: myapp
3. Use the secrets
In code it looks simple:
@Value("${database.username}")
private String username;
@Value("${database.password}")
private String password;
Verifying it works
Create a simple REST controller:
@RestController
public class TestController {
@Value("${database.username}")
private String username;
@GetMapping("/test")
public String test() {
return "Connected as: " + username;
}
}
Run the app and check:
curl http://localhost:8080/test
Useful features
1. Updating secrets "on the fly"
Change the secret in Vault:
vault kv put secret/myapp/database \
username=newuser \
password=newpass
And refresh the app configuration:
curl -X POST http://localhost:8080/actuator/refresh
2. Different secrets for different environments
In Vault:
vault kv put secret/myapp/database/dev \
username=devuser \
password=devpass
vault kv put secret/myapp/database/prod \
username=produser \
password=prodpass
In the app:
spring:
cloud:
vault:
kv:
default-context: myapp/database/${spring.profiles.active}
Advanced techniques: real-time updates
Hook up Spring Cloud Bus
In pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Configure RabbitMQ
In application.yml:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
cloud:
bus:
enabled: true
Automatic secret refresh
Now when a secret changes in Vault:
- We send an event to RabbitMQ
- Spring Cloud Bus delivers it to all microservices
- Each service refreshes its secrets
Working with multiple environments
Secret structure in Vault
secret/
├── dev/
│ ├── app1/
│ └── app2/
├── staging/
│ ├── app1/
│ └── app2/
└── prod/
├── app1/
└── app2/
Configuring Spring profiles
In bootstrap.yml:
spring:
cloud:
vault:
kv:
application-name: ${spring.application.name}/${spring.profiles.active}
Common problems and fixes
1. Vault is unavailable at startup
Add to application.yml:
spring:
cloud:
vault:
fail-fast: false
config:
lifecycle:
enabled: true
2. Secrets are not refreshing
Don't forget to add:
@RefreshScope
public class MyConfig {
// ...
}
Homework
- Install Vault locally
- Create a simple Spring Boot application
- Set up storing and retrieving at least three different secrets
- Bonus: set up working with different profiles (dev/prod)
In the next lecture we'll look at advanced Vault topics: access policies, audit, and automatic secret rotation.
See you in the lab! And don't forget to clear your terminal history — there might be secrets left in there
GO TO FULL VERSION