# HiveOps Config Server Implementation Plan
## Context
This plan addresses the implementation of a centralized configuration server (hiveops-config) for the HiveOps microservices ecosystem. The goal is to provide externalized, version-controlled configuration management using Spring Cloud Config Server.
**Motivation**: Currently, each microservice (hiveops-mgmt, hiveops-auth, hiveops-incident) manages its configuration independently through application.yml files and environment variables. This creates challenges:
- Configuration drift between environments (dev, staging, prod)
- No centralized view of all service configurations
- Difficult to audit configuration changes
- No version control for configuration history
- Shared settings (like JWT secrets) duplicated across services
**Solution**: Implement Spring Cloud Config Server to centralize configuration in a Git repository with environment-specific profiles, enabling version control, audit trails, and consistent configuration across all services.
**Existing Microservices:**
- **hiveops-mgmt** (port 8080): License management, internal user authentication
- **hiveops-incident** (port 8081): Incident management and workflow
- **hiveops-auth** (port 8082): Customer authentication with MFA
**New Service:**
- **hiveops-config** (port 8083): Centralized configuration server
## Architecture Decision
### Spring Cloud Config Server with Git Backend
**Approach: Centralized configuration with local/remote Git repository storage**
```
Configuration Flow:
Git Repository (config-repo/)
├── application.yml # Shared defaults
├── hiveops-mgmt.yml # mgmt-specific config
├── hiveops-mgmt-dev.yml # mgmt dev profile
├── hiveops-mgmt-prod.yml # mgmt prod profile
├── hiveops-auth.yml # auth-specific config
├── hiveops-auth-dev.yml # auth dev profile
├── hiveops-auth-prod.yml # auth prod profile
├── hiveops-incident.yml # incident-specific config
├── hiveops-incident-dev.yml # incident dev profile
└── hiveops-incident-prod.yml # incident prod profile
↓
hiveops-config (Spring Cloud Config Server)
- Serves configuration over HTTP
- Port 8083
- Secure endpoints with HTTP Basic Auth
- Health checks and monitoring
↓
Client Services (mgmt, incident, auth)
- Bootstrap phase: connect to config server
- Load configuration before application startup
- Support for config refresh without restart (@RefreshScope)
```
**Benefits:**
- Version control for all configurations (Git history)
- Environment-specific profiles (dev, prod, staging)
- Centralized security settings
- Dynamic configuration updates without redeployment
- Audit trail via Git commits
- Easy rollback to previous configurations
- Shared configuration elimination (e.g., JWT secrets defined once)
## Project Structure
```
hiveops-config/
├── src/main/
│ ├── java/com/hiveops/config/
│ │ ├── HiveopsConfigServerApplication.java # Main class with @EnableConfigServer
│ │ └── config/
│ │ └── SecurityConfig.java # HTTP Basic Auth for config endpoints
│ │
│ └── resources/
│ ├── application.yml # Config server settings (dev)
│ └── application-prod.yml # Prod profile (remote git)
│
├── config-repo/ # Local Git repository for configurations
│ ├── application.yml # Shared defaults
│ ├── hiveops-mgmt.yml
│ ├── hiveops-mgmt-dev.yml
│ ├── hiveops-mgmt-prod.yml
│ ├── hiveops-auth.yml
│ ├── hiveops-auth-dev.yml
│ ├── hiveops-auth-prod.yml
│ ├── hiveops-incident.yml
│ ├── hiveops-incident-dev.yml
│ ├── hiveops-incident-prod.yml
│ └── .gitignore
│
├── devops-scripts/
│ ├── build-and-push.sh
│ ├── deploy.sh
│ └── docker/
│ └── .env.example
│
├── Dockerfile # Multi-stage Alpine build
├── docker-compose.yml # Dev environment
├── docker-compose.prod.yml # Prod deployment
├── pom.xml
└── README.md
```
## Spring Cloud Config Server Implementation
### Key Dependencies (pom.xml)
```xml
org.springframework.boot
spring-boot-starter-parent
3.4.1
21
2023.0.3
org.springframework.cloud
spring-cloud-config-server
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-security
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.security
spring-security-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
```
### Main Application Class
```java
package com.hiveops.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class HiveopsConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(HiveopsConfigServerApplication.class, args);
}
}
```
### Security Configuration (HTTP Basic Auth)
```java
package com.hiveops.config.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Value("${config.security.username}")
private String username;
@Value("${config.security.password}")
private String password;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health", "/actuator/info").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.csrf(csrf -> csrf.disable());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.builder()
.username(username)
.password(passwordEncoder().encode(password))
.roles("CONFIG_CLIENT")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
```
### Config Server Configuration (application.yml)
```yaml
server:
port: 8083
spring:
application:
name: hiveops-config-server
cloud:
config:
server:
git:
uri: file://${user.dir}/config-repo # Dev: local repo
default-label: main
clone-on-start: true
force-pull: true
# Security credentials
config:
security:
username: ${CONFIG_USERNAME:config-user}
password: ${CONFIG_PASSWORD:changeme}
# Actuator endpoints
management:
endpoints:
web:
exposure:
include: health,info,env,refresh
endpoint:
health:
show-details: always
# Logging
logging:
level:
root: INFO
org.springframework.cloud.config: DEBUG
```
### Production Configuration (application-prod.yml)
```yaml
spring:
cloud:
config:
server:
git:
uri: ${GIT_REPO_URL} # Remote git repository URL
username: ${GIT_USERNAME}
password: ${GIT_PASSWORD}
default-label: main
clone-on-start: true
force-pull: true
timeout: 10
# Security (from environment variables)
config:
security:
username: ${CONFIG_USERNAME}
password: ${CONFIG_PASSWORD}
```
## Configuration Repository Structure
### Naming Convention
Spring Cloud Config uses this pattern:
```
{application}-{profile}.yml
```
Where:
- `{application}` = spring.application.name from client service
- `{profile}` = spring.profiles.active from client service
### Example Configurations
**application.yml** (shared across all services):
```yaml
# Shared configuration for all HiveOps microservices
logging:
level:
root: INFO
com.hiveops: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg%n"
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
```
**hiveops-auth-prod.yml** (auth service production config):
```yaml
server:
port: 8082
spring:
datasource:
url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:hiveops_auth}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
# JWT Configuration (shared secret with other services)
jwt:
secret: ${JWT_SECRET}
expiration: 86400000
refresh-expiration: 604800000
# MFA Configuration
mfa:
secret-encryption-key: ${MFA_ENCRYPTION_KEY}
totp-algorithm: SHA1
totp-digits: 6
totp-period: 30
backup-code-count: 10
# Rate Limiting
rate-limit:
ip:
capacity: 20
refill-tokens: 20
refill-duration-minutes: 1
user:
capacity: 5
refill-tokens: 5
refill-duration-minutes: 15
```
## Client Service Integration
### Required Changes in Existing Services
For each service (hiveops-mgmt, hiveops-auth, hiveops-incident):
**1. Add Dependencies to pom.xml:**
```xml
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-bootstrap
```
**2. Create bootstrap.yml** (loaded before application.yml):
```yaml
spring:
application:
name: hiveops-auth # Change per service: hiveops-mgmt, hiveops-incident
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
cloud:
config:
uri: ${CONFIG_SERVER_URL:http://localhost:8083}
username: ${CONFIG_USERNAME:config-user}
password: ${CONFIG_PASSWORD:changeme}
fail-fast: true # Fail startup if config server unreachable
retry:
initial-interval: 1000
max-interval: 2000
max-attempts: 6
```
**3. Configuration Migration Strategy:**
- Keep application.yml for local defaults (fallback when config server disabled)
- Move environment-specific config to config-repo/{service}-{profile}.yml
- Secrets remain in environment variables, referenced in config files
## Docker Deployment
### Dockerfile (Multi-Stage Alpine Build)
Following established HiveOps pattern:
```dockerfile
# Build stage
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
# Copy Maven files
COPY pom.xml .
COPY src ./src
# Build the application
RUN apk add --no-cache maven && \
mvn clean package -DskipTests && \
mv target/*.jar app.jar
# Runtime stage
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
# Create non-root user
RUN addgroup -S hiveops && adduser -S hiveops -G hiveops
# Copy JAR from builder
COPY --from=builder /app/app.jar .
# Copy config repository (for development)
COPY config-repo ./config-repo
# Initialize git in config-repo
RUN apk add --no-cache git && \
cd config-repo && \
git init && \
git config user.email "config@hiveops.com" && \
git config user.name "Config Server" && \
git add . && \
git commit -m "Initial commit" || true
# Change ownership
RUN chown -R hiveops:hiveops /app
# Switch to non-root user
USER hiveops
# Expose port
EXPOSE 8083
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8083/actuator/health || exit 1
# Run application
ENTRYPOINT ["java", "-jar", "app.jar"]
```
### docker-compose.yml (Development)
```yaml
version: '3.8'
services:
hiveops-config:
build: .
container_name: hiveops-config-dev
ports:
- "8083:8083"
environment:
- SPRING_PROFILES_ACTIVE=dev
- CONFIG_USERNAME=config-user
- CONFIG_PASSWORD=dev-password
volumes:
- ./config-repo:/app/config-repo
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8083/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- hiveops-network
networks:
hiveops-network:
driver: bridge
```
### docker-compose.prod.yml (Production)
```yaml
version: '3.8'
services:
hiveops-config:
image: ${REGISTRY_URL}/hiveops-config:${VERSION:-latest}
container_name: hiveops-config-prod
restart: unless-stopped
ports:
- "8083:8083"
environment:
- SPRING_PROFILES_ACTIVE=prod
- CONFIG_USERNAME=${CONFIG_USERNAME}
- CONFIG_PASSWORD=${CONFIG_PASSWORD}
- GIT_REPO_URL=${GIT_REPO_URL}
- GIT_USERNAME=${GIT_USERNAME}
- GIT_PASSWORD=${GIT_PASSWORD}
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8083/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- hiveops-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
hiveops-network:
external: true
```
## DevOps Scripts (Following Standard Pattern)
### build-and-push.sh
```bash
#!/bin/bash
set -e
# Configuration
SERVICE_NAME="hiveops-config"
REGISTRY_URL="${REGISTRY_URL:-registry.hiveops.com}"
# Get version from pom.xml
VERSION=$(grep -oP '\K[^<]+' pom.xml | head -1)
echo "Building $SERVICE_NAME version $VERSION..."
# Build Docker image
docker build -t $SERVICE_NAME:$VERSION .
docker tag $SERVICE_NAME:$VERSION $SERVICE_NAME:latest
# Tag for registry
docker tag $SERVICE_NAME:$VERSION $REGISTRY_URL/$SERVICE_NAME:$VERSION
docker tag $SERVICE_NAME:latest $REGISTRY_URL/$SERVICE_NAME:latest
# Login to registry
if [ -n "$REGISTRY_USERNAME" ] && [ -n "$REGISTRY_PASSWORD" ]; then
echo "$REGISTRY_PASSWORD" | docker login $REGISTRY_URL -u "$REGISTRY_USERNAME" --password-stdin
fi
# Push to registry
echo "Pushing to registry..."
docker push $REGISTRY_URL/$SERVICE_NAME:$VERSION
if [ "$VERSION" != "latest" ]; then
docker push $REGISTRY_URL/$SERVICE_NAME:latest
fi
echo "Build and push completed successfully!"
echo "Image: $REGISTRY_URL/$SERVICE_NAME:$VERSION"
```
### deploy.sh
```bash
#!/bin/bash
set -e
SERVICE_NAME="hiveops-config"
COMPOSE_FILE="docker-compose.prod.yml"
# Check if docker-compose.prod.yml exists
if [ ! -f "$COMPOSE_FILE" ]; then
COMPOSE_FILE="docker-compose.yml"
fi
echo "Deploying $SERVICE_NAME..."
# Load environment variables
if [ -f "devops-scripts/docker/.env" ]; then
export $(cat devops-scripts/docker/.env | grep -v '^#' | xargs)
fi
# Pull latest image
docker-compose -f $COMPOSE_FILE pull
# Stop and remove old containers
docker-compose -f $COMPOSE_FILE down
# Start new containers
docker-compose -f $COMPOSE_FILE up -d
# Wait for health check
echo "Waiting for service to be healthy..."
sleep 10
# Check health
if docker ps | grep -q $SERVICE_NAME; then
echo "$SERVICE_NAME deployed successfully!"
docker-compose -f $COMPOSE_FILE logs --tail=50
else
echo "Deployment failed!"
docker-compose -f $COMPOSE_FILE logs
exit 1
fi
```
### devops-scripts/docker/.env.example
```bash
# Registry Configuration
REGISTRY_URL=registry.hiveops.com
REGISTRY_USERNAME=deploy-user
REGISTRY_PASSWORD=changeme
# Version
VERSION=1.0.0
# Config Server Security
CONFIG_USERNAME=config-user
CONFIG_PASSWORD=changeme-strong-password
# Git Repository (Production)
GIT_REPO_URL=https://github.com/hiveops/config-repo.git
GIT_USERNAME=git-user
GIT_PASSWORD=git-token
# Network
NETWORK_NAME=hiveops-network
```
## Testing Strategy
### Unit Tests
```java
package com.hiveops.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class ConfigServerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(roles = "CONFIG_CLIENT")
void shouldServeConfiguration() throws Exception {
mockMvc.perform(get("/hiveops-mgmt/dev"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("hiveops-mgmt"))
.andExpect(jsonPath("$.profiles[0]").value("dev"));
}
@Test
void healthEndpointShouldBePublic() throws Exception {
mockMvc.perform(get("/actuator/health"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("UP"));
}
@Test
void configEndpointShouldRequireAuth() throws Exception {
mockMvc.perform(get("/hiveops-mgmt/dev"))
.andExpect(status().isUnauthorized());
}
}
```
## Critical Files to Create
### New Project Files
1. `/source/hiveops-src/hiveops-config/pom.xml`
- Maven dependencies (Spring Cloud Config Server, Security, Actuator)
2. `/source/hiveops-src/hiveops-config/src/main/java/com/hiveops/config/HiveopsConfigServerApplication.java`
- Main class with @EnableConfigServer annotation
3. `/source/hiveops-src/hiveops-config/src/main/java/com/hiveops/config/config/SecurityConfig.java`
- HTTP Basic Auth configuration
4. `/source/hiveops-src/hiveops-config/src/main/resources/application.yml`
- Config server settings (dev profile with local git repo)
5. `/source/hiveops-src/hiveops-config/src/main/resources/application-prod.yml`
- Production profile (remote git repo)
6. `/source/hiveops-src/hiveops-config/config-repo/application.yml`
- Shared configuration for all services
7. `/source/hiveops-src/hiveops-config/config-repo/hiveops-mgmt.yml`
- mgmt service base configuration
8. `/source/hiveops-src/hiveops-config/config-repo/hiveops-mgmt-dev.yml`
- mgmt service dev profile
9. `/source/hiveops-src/hiveops-config/config-repo/hiveops-mgmt-prod.yml`
- mgmt service prod profile
10. `/source/hiveops-src/hiveops-config/config-repo/hiveops-auth.yml`
- auth service base configuration
11. `/source/hiveops-src/hiveops-config/config-repo/hiveops-auth-dev.yml`
- auth service dev profile
12. `/source/hiveops-src/hiveops-config/config-repo/hiveops-auth-prod.yml`
- auth service prod profile
13. `/source/hiveops-src/hiveops-config/config-repo/hiveops-incident.yml`
- incident service base configuration
14. `/source/hiveops-src/hiveops-config/config-repo/hiveops-incident-dev.yml`
- incident service dev profile
15. `/source/hiveops-src/hiveops-config/config-repo/hiveops-incident-prod.yml`
- incident service prod profile
16. `/source/hiveops-src/hiveops-config/config-repo/.gitignore`
- Ignore patterns for config repo
17. `/source/hiveops-src/hiveops-config/Dockerfile`
- Multi-stage Alpine build
18. `/source/hiveops-src/hiveops-config/docker-compose.yml`
- Development environment
19. `/source/hiveops-src/hiveops-config/docker-compose.prod.yml`
- Production deployment
20. `/source/hiveops-src/hiveops-config/devops-scripts/build-and-push.sh`
- Build and push script
21. `/source/hiveops-src/hiveops-config/devops-scripts/deploy.sh`
- Deployment script
22. `/source/hiveops-src/hiveops-config/devops-scripts/docker/.env.example`
- Environment variables template
23. `/source/hiveops-src/hiveops-config/README.md`
- Documentation
24. `/source/hiveops-src/hiveops-config/src/test/java/com/hiveops/config/ConfigServerIntegrationTest.java`
- Integration tests
### Modified Files (Client Services)
**For each service: hiveops-mgmt, hiveops-auth, hiveops-incident**
1. `pom.xml`
- Add spring-cloud-starter-config dependency
- Add spring-cloud-starter-bootstrap dependency
- Add spring-cloud-dependencies BOM
2. `src/main/resources/bootstrap.yml` (NEW)
- Config server connection settings
3. `devops-scripts/docker/.env.example`
- Add CONFIG_SERVER_URL, CONFIG_USERNAME, CONFIG_PASSWORD
4. `docker-compose.yml` and `docker-compose.prod.yml`
- Add config server environment variables
- Add dependency on hiveops-config service
## Verification Steps
### 1. Config Server Startup
```bash
cd /source/hiveops-src/hiveops-config
mvn spring-boot:run
# Expected log output:
# "Fetching config from local git repository at file://.../config-repo"
# "Started HiveopsConfigServerApplication in X.XXX seconds"
```
### 2. Health Check
```bash
curl http://localhost:8083/actuator/health
# Expected:
# {"status":"UP"}
```
### 3. Configuration Retrieval (Authenticated)
```bash
# Get mgmt dev configuration
curl -u config-user:changeme http://localhost:8083/hiveops-mgmt/dev
# Expected: JSON response with:
# - name: "hiveops-mgmt"
# - profiles: ["dev"]
# - propertySources: [array of config files]
```
### 4. Security Verification
```bash
# Without credentials should fail
curl http://localhost:8083/hiveops-mgmt/dev
# Expected: HTTP 401 Unauthorized
```
### 5. Client Service Integration
```bash
# Start config server
cd /source/hiveops-src/hiveops-config
mvn spring-boot:run &
# Start mgmt service with config client enabled
cd /source/hiveops-src/hiveops-mgmt
export CONFIG_SERVER_URL=http://localhost:8083
export CONFIG_USERNAME=config-user
export CONFIG_PASSWORD=changeme
mvn spring-boot:run
# Check logs for:
# "Fetching config from server at: http://localhost:8083"
# "Located environment: name=hiveops-mgmt, profiles=[dev]"
# Verify config loaded
curl http://localhost:8080/actuator/env | jq '.propertySources[] | select(.name | contains("configServer"))'
```
### 6. Docker Build and Run
```bash
# Build Docker image
cd /source/hiveops-src/hiveops-config
docker build -t hiveops-config:1.0.0 .
# Run container
docker run -d -p 8083:8083 \
-e CONFIG_USERNAME=config-user \
-e CONFIG_PASSWORD=changeme \
--name hiveops-config \
hiveops-config:1.0.0
# Test health
curl http://localhost:8083/actuator/health
```
## Migration Strategy
### Phase 1: Create Config Server (Week 1)
**Tasks:**
1. Create hiveops-config project structure
2. Implement config server with security
3. Create config-repo with initial configurations (migrate from existing application.yml files)
4. Deploy to dev environment
5. Run tests to verify config serving
**Verification:**
- Config server starts successfully
- Health endpoint returns UP
- Can retrieve configurations via HTTP
- Security requires authentication
### Phase 2: Integrate hiveops-mgmt (Week 2)
**Tasks:**
1. Add Spring Cloud Config dependencies to hiveops-mgmt/pom.xml
2. Create bootstrap.yml with config server connection
3. Copy current application-prod.yml content to config-repo/hiveops-mgmt-prod.yml
4. Test mgmt service with config server in dev environment
5. Verify all existing functionality works
**Rollback plan:** Keep application.yml as fallback if config server unavailable
### Phase 3: Integrate hiveops-auth (Week 3)
**Tasks:**
1. Add dependencies to hiveops-auth/pom.xml
2. Create bootstrap.yml
3. Move auth configuration to config-repo
4. Test authentication flows
5. Deploy to staging
### Phase 4: Integrate hiveops-incident (Week 4)
**Tasks:**
1. Add dependencies to hiveops-incident/pom.xml
2. Create bootstrap.yml
3. Move incident configuration to config-repo
4. Test incident workflows
5. Deploy to staging
### Phase 5: Production Deployment (Week 5)
**Tasks:**
1. Create production config repository (separate Git repo on Gitea)
2. Deploy config server to production
3. Update all services to use prod config server
4. Monitor logs and health checks
5. Document configuration management process
**Deployment order:**
1. hiveops-config (no dependencies)
2. hiveops-mgmt (depends on config)
3. hiveops-auth (depends on config)
4. hiveops-incident (depends on config)
## Security Considerations
### 1. Config Server Security
- **HTTP Basic Authentication**: Required for all config endpoints
- **Strong passwords**: Use environment variables, never hardcode
- **HTTPS in production**: Use TLS certificates
- **Network isolation**: Deploy in private network
### 2. Git Repository Security
- **Private repository**: Never use public repos for production configs
- **Access tokens**: Use personal access tokens instead of passwords
- **Branch protection**: Require PR reviews for config changes
- **Audit logging**: Track who changed what configuration
### 3. Secrets Management
**Never commit secrets to Git**
```yaml
# Good: Reference environment variables
spring:
datasource:
password: ${DB_PASSWORD}
# Bad: Hardcoded secrets
spring:
datasource:
password: mySecretPassword123
```
### 4. Configuration Encryption (Future Enhancement)
Spring Cloud Config supports encryption:
```yaml
encrypt:
key: ${ENCRYPT_KEY} # Symmetric key for encryption/decryption
# Encrypted values in config files:
spring:
datasource:
password: '{cipher}AQA2J5...' # Encrypted
```
## Configuration Best Practices
### 1. Property Naming Convention
```yaml
# Use hierarchical structure
hiveops:
mgmt:
license:
offline-grace-period: 7
validation-interval: 24
auth:
mfa:
enabled: true
totp-digits: 6
```
### 2. Environment Separation
```
config-repo/
├── application.yml # Common to all
├── hiveops-mgmt-dev.yml # Dev-specific
├── hiveops-mgmt-staging.yml # Staging-specific
├── hiveops-mgmt-prod.yml # Prod-specific
```
### 3. Configuration Documentation
Add comments to config files:
```yaml
# hiveops-auth.yml
# MFA Configuration
# totp-digits: Number of digits in TOTP code (6 or 8)
# totp-period: Time period in seconds (typically 30)
mfa:
totp-digits: 6
totp-period: 30
```
### 4. Git Workflow
- **Feature branches**: Create branch for config changes
- **Pull requests**: Require review before merging
- **Version tags**: Tag releases (v1.0.0, v1.1.0)
- **Rollback**: Easy to revert to previous commit
---
**Last Updated**: 2026-02-13