Spring Boot Vault Integration Testing with Testcontainers | Guide


Explanation:

  • Spring Boot: Represents the Spring Boot application.
  • Testcontainers: This section represents the Testcontainers framework that spins up the Vault container for integration testing.
  • Vault Container: Represents the Vault container that is managed by Testcontainers.
  • Vault: Represents HashiCorp Vault itself.

To integrate Spring Boot with HashiCorp Vault using Testcontainers for end-to-end testing, we need to follow these steps:

Docker Setup 

Install Docker: Download and install Docker from Docker's official website.
  • Windows/macOS: Install and run Docker Desktop.
  • Linux: Install Docker Engine using your package manager.
Verify Installation:
Run docker --version to confirm Docker is installed.
Start Docker:
  • Windows/macOS: Launch Docker Desktop and ensure it’s running.
  • Linux: Start Docker with sudo systemctl start docker.


Add Dependencies

Add the required dependencies in your pom.xml for Spring Boot, HashiCorp Vault, and Testcontainers.

<properties>
    <java.version>17</java.version>
    <spring-cloud.version>2024.0.0</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-vault-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-testcontainers</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>vault</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<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>


Spring Boot Configuration

Set up your application.yml or application.properties for Vault integration.
spring:
  cloud:
    vault:
      uri: http://localhost:8200
      authentication: TOKEN
      token: <your_vault_token>
      kv:
        enabled: true
        backend: secret
        default-context: application

 

Testcontainers Setup

Create a test class for the Vault container setup. You can use Testcontainers to spin up a Vault instance for integration testing.

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.containers.VaultContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@ExtendWith(SpringExtension.class)
@Testcontainers
@SpringBootTest
public class VaultIntegrationTest {

    @Container
    public static VaultContainer vault = new VaultContainer("vault:latest")
            .withExposedPorts(8200)
            .withVaultToken("myroot");

    @Autowired
    private YourService yourService;

    @BeforeAll
    static void setUp() {
        // Initialize Vault with secrets
        vault.execInContainer("vault", "kv", "put", "secret/myapp", "key=value");
    }

    @Test
    void testVaultIntegration() {
        // Your test code interacting with the Vault service
        String secret = yourService.getSecretFromVault();
        assertNotNull(secret);
        assertEquals("value", secret);
    }
}
  • The @Container annotation spins up the Vault container before tests run.
  • In the setUp() method, we initialize the Vault container and add some secrets for testing.
  • The @SpringBootTest annotation loads the Spring context for the test.


Service Class

You need to create a service class that interacts with Vault. You can use Spring's VaultTemplate or the @Value annotation to inject secrets from Vault.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class YourService {

    @Value("${secret.myapp.key}")
    private String secretKey;

    public String getSecretFromVault() {
        return secretKey;
    }
}

Run the Test

With the setup complete, you can run the tests. The Vault container will start up, and Spring Boot will load the secrets from the Vault instance for the test.
./mvnw test

This setup ensures that you have an end-to-end test for your Spring Boot application that interacts with HashiCorp Vault, running inside a Testcontainers-managed container.

Comments

Popular posts from this blog

Spring Boot OpenAI Integration: Step-by-Step Guide

Orchestration-Based Saga Architecture and Spring Boot Microservices Implementation Guide

Spring Boot 3 + Angular 15 + Material - Full Stack CRUD Application Example