Skip to content

Commit 85176e6

Browse files
Merge pull request #13 from HomeOfTheWizard/develop
prepare release 1.1.3
2 parents 795cd55 + cc29490 commit 85176e6

File tree

20 files changed

+559
-42
lines changed

20 files changed

+559
-42
lines changed

docs/_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
title: vault-maven-plugin
2222
logo: "/assets/images/Vault-Maven-Plugin-colored.png"
23+
favicon_ico: "assets/images/favicon.png"
2324
2425
description: >- # this means to ignore newlines until "baseurl:"
2526
Vault Maven Plugin is a plugin that allows fetching secrets from vault during the maven build of your project.

docs/assets/images/favicon.png

7.02 KB
Loading
Loading

docs/assets/images/intellij_debug.PNG

64.9 KB
Loading

docs/assets/images/new way.png

15.7 KB
Loading

docs/assets/images/old vs new way.png

30.3 KB
Loading

docs/assets/images/old way.png

17.6 KB
Loading

docs/favicon.ico

7.02 KB
Binary file not shown.

docs/index.markdown

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
layout: page
33
title: About Vault Maven Plugin
4+
nav_order: 1
45
---
56

67
# No need to store your credentials locally anymore
@@ -34,35 +35,42 @@ or some encryption keys for securing the communication itself.
3435
[Hashicorp Vault](https://www.vaultproject.io/) allows us to securely store those secrets, and share them with necessary counterparts.
3536
Those counterparts may be developers who want to run the application on their local environments, or the application's different execution environments (Test, Production, CI ect...)
3637

37-
{: .warning }
3838
Organisations that has a Hashicorp Vault, in general, are already using a cloud based architecture.
3939
Hence, already have some ways for the application's credentials to be fetched automatically from Vault, instead of storing them locally on each environment separately.
4040
Ex: Orchestrated Container environments like Kubernetes,
4141
or CI tools like Jenkins have a Vault plugin to do so.
42-
The idea behind using those tools, is to fetch the credentials in advance, to speed up the start time of your application.
4342

44-
But it may be the case that :
45-
* Your enterprise's IT infrastructure does not have such tools yet,
46-
* It may be in a transition phase, or maybe some legacy applications that are not compatible with such tools.
47-
* For some reason even if you have such tools, the Vault plugins are not available.
48-
* Such tools are not available on developers' local environments,
49-
where lots of enterprises still provide Windows PCs without a Docker or K8s.
50-
51-
This plugin aims to help those cases :santa:.
52-
53-
**But not only!** There are some cases where we don't want to store any configuration related to Vault in any execution environment, but only credentials to access it.
54-
For example batch applications may prefer to tradeoff for the simplicity of configuration over the speed of startup :massage_man:.
43+
{: .warning }
44+
All those plugins/tools, all require you to declare your secrets on their own configuration file, causing duplication among different config files.
5545

5646
{: .important }
57-
In short, this plugin gives you a simpler and more secure way to manage your secrets.
58-
Everything, except the credentials to vault, can be stored on version control.
47+
By using this plugin to fetch your secrets, you can unify all your configuration and secrets declaration in a single file, the pom.xml.
48+
So everything, except the credentials to vault, can be stored on version control.
5949
And if you use Github PAT authentication, even that can be on version control!
6050

6151
{: .warning }
62-
Just keep in mind that fetching the secrets in time of execution has an implication of I/O, network and additional time of startup.
52+
The idea behind using those plugins/tools, like jenkins Vault plugin or the Vault Agent that is used to save your secrets on K8s, is to fetch the credentials in advance, so that they are available right away at the start time of your application, making it to boot faster.
53+
54+
{: .important }
55+
But there are some cases, for example batch applications, where we may prefer to tradeoff for the simplicity of configuration over the speed of startup :massage_man:.
56+
Just keep in mind that fetching the secrets in time of execution has an implication of I/O, network and additional time of startup.
57+
58+
But still If you are sensible to the boot time of your application, lets say you have a web scaling app running on K8s,
59+
You can still use this plugin, still with a single definition of your secrets in the pom.xml, to create your secret.yaml for K8s at its deployment time instead of the boot time. :wink:
60+
61+
62+
But it may also be the case that :
63+
* Your enterprise's IT infrastructure does not have such tools yet,
64+
* It may be in a transition phase, or maybe some legacy applications that are not compatible with such tools.
65+
* For some reason even if you have such tools, the Vault plugins are not available.
66+
* **Such tools are not available on developers' local environments,**
67+
where lots of enterprises still provide Windows PCs without a Docker or K8s.
68+
69+
This plugin aims to help all those cases :santa:.
70+
6371

6472
## Example use cases
65-
Some CI tools that already working with maven, for example maven plugins, like liquibase or sonar-scanner plugins,
73+
Some CI tools that already working with maven, for example liquibase or sonar-scanner which both have maven plugins,
6674
are the best suite for using the Vault Maven Plugin.
6775

6876
Java applications that use maven to build/package can also profit from it.

docs/usage.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
layout: page
33
title: How to use it
4+
nav_order: 2
45
---
56

67
## How to configure it

docs/use-cases/appTypes.markdown

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
---
2+
layout: page
3+
title: By Application Type
4+
parent: Practical use cases
5+
---
6+
7+
# 1. Other maven plugins
8+
Many CI tools are used via maven plugins for the convenience of not having to manage executables.
9+
Sonar scanner and liquibase are one of them.
10+
The example below shows you how to fetch the credentials necessary to use those plugins, via the vault-maven-plugin.
11+
12+
Let's say you are using liquibase and have the following pom.xml
13+
```xml
14+
<build>
15+
<plugins>
16+
<plugin>
17+
<groupId>org.liquibase</groupId>
18+
<artifactId>liquibase-maven-plugin</artifactId>
19+
<version>4.6.1</version>
20+
<executions>
21+
<execution>
22+
<phase>compile</phase>
23+
<goals>
24+
<goal>update</goal>
25+
</goals>
26+
</execution>
27+
</executions>
28+
<configuration>
29+
<propertyFile>target/classes/liquibase.properties</propertyFile>
30+
</configuration>
31+
</plugin>
32+
</plugins>
33+
<resources>
34+
<resource>
35+
<directory>src/main/resources</directory>
36+
<filtering>true</filtering>
37+
<includes>
38+
<include>*.properties</include>
39+
</includes>
40+
</resource>
41+
</resources>
42+
</build>
43+
```
44+
45+
Your property file might be like below.
46+
```properties
47+
changeLogFile=src/main/resources/liquibase/.../changelog.xml
48+
url=...
49+
database=...
50+
username=...
51+
password=${database.password}
52+
```
53+
54+
Usually the property `database.password` if given to maven as system property or environment variables.
55+
56+
If you don't have a tool that will fetch the secret and create the environment variable for you, you can use the maven vault plugin.
57+
You just add the following to fetch the secrets and inject them as properties in maven.
58+
```xml
59+
<plugin>
60+
<groupId>com.homeofthewizard</groupId>
61+
<artifactId>vault-maven-plugin</artifactId>
62+
<version>1.1.2-SNAPSHOT</version>
63+
<executions>
64+
<execution>
65+
<id>pull</id>
66+
<phase>initialize</phase>
67+
<goals>
68+
<goal>pull</goal>
69+
</goals>
70+
</execution>
71+
</executions>
72+
<configuration>
73+
<servers>
74+
<server>
75+
<url>https://your-vault-host</url>
76+
<token>XXXXXXX</token>
77+
<paths>
78+
<path>
79+
<name>secret/data/some-app</name>
80+
<mappings>
81+
<mapping>
82+
<key>vaultSecretKey</key>
83+
<property>database.password</property>
84+
</mapping>
85+
</mappings>
86+
</path>
87+
</paths>
88+
</server>
89+
</servers>
90+
</configuration>
91+
</plugin>
92+
```
93+
94+
and Voilà! :tada:
95+
When you execute your liquibase plugin `mvn clean compile`,
96+
the vault plugin will fetch the secrets,
97+
the resource plugin will put it in the property file by replacing the placeholder,
98+
then the liquibase plugin will run using the secret!
99+
100+
No need to handle secrets in the execution environment anymore ! :massage_man:
101+
You only need to give set the execution environment's credentials to access Vault!
102+
103+
# 2. Maven Applications
104+
105+
{: .warning }
106+
As already mentionned [here](https://homeofthewizard.github.io/vault-maven-plugin/#example-use-cases), if your application is using Spring-Cloud,
107+
You should use [Spring Cloud Vault](https://spring.io/projects/spring-cloud-vault) instead of this maven plugin.
108+
109+
Many Java application like Spring applications externalise their configurations in a property file,
110+
as recommended by the [12 factor app](https://12factor.net/config).
111+
Secrets are part of those configuration files. The configuration file can be stored in version control.
112+
But a good security practice is not to store the secrets on version control.
113+
Hence, the secrets are fetched generally from environment variables on the system where we run the app.
114+
115+
You can do the following to fetch the secrets from vault via the Vault Plugin,
116+
then run your application with maven, and your secrets will be injected as system properties.
117+
118+
Let's say you are using Spring and have the following `application.properties`
119+
```properties
120+
app.secret=${APPLICATION_SECRET}
121+
```
122+
123+
You can define the following in your pom.xml to fetch the credential for `APPLICATION_SECRET`.
124+
```xml
125+
<plugins>
126+
<plugin>
127+
<groupId>com.homeofthewizard</groupId>
128+
<artifactId>vault-maven-plugin</artifactId>
129+
<version>1.1.2-SNAPSHOT</version>
130+
<executions>
131+
<execution>
132+
<id>pull</id>
133+
<phase>initialize</phase>
134+
<goals>
135+
<goal>pull</goal>
136+
</goals>
137+
</execution>
138+
</executions>
139+
<configuration>
140+
<servers>
141+
<server>
142+
<url>https://your-vault-host</url>
143+
<token>XXXXXXX</token>
144+
<paths>
145+
<path>
146+
<name>secret/data/some-app</name>
147+
<mappings>
148+
<mapping>
149+
<key>vaultSecretKey</key>
150+
<property>APPLICATION_SECRET</property>
151+
</mapping>
152+
</mappings>
153+
</path>
154+
</paths>
155+
</server>
156+
</servers>
157+
<outputMethod>SystemProperties</outputMethod>
158+
</configuration>
159+
</plugin>
160+
</plugins>
161+
```
162+
163+
The above code will first fetch the secrets from vault with the vault-plugin, then they will be added to Maven's system properties (`<outputMethod>` configuration).
164+
After that you can run your java app with either [exec-maven-plugin](http://www.mojohaus.org/exec-maven-plugin/usage.html) or the [spring-boot-maven-plugin](https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/)
165+
By running your application with maven, maven's system properties will be shared with your application.
166+
167+
<p><img src="../assets/images/old%20vs%20new%20way.png"/></p>
168+
169+
### In case you have a Non-Spring Java application
170+
Spring boot manages system properties and environment variables differently that the standard way.
171+
You will find here a [blog post](https://homeofthewizard.github.io/secrets-in-java) that explains how the two works in java, and [here](https://www.baeldung.com/spring-boot-properties-env-variables) a post explaining spring's difference.
172+
But in short, Spring allows you to access both via the same API (using placeholders like `${myVar}`). So for a spring application that requires environment variables, we can emulate them by injecting System properties instead.
173+
174+
For a non Spring application that requires environment variables, we cannot do that, we need to give the JVM real environment variables.
175+
Let's say you have a simple java application, with a main class like this
176+
```java
177+
package org.example;
178+
179+
public class Main {
180+
public static void main(String[] args) {
181+
System.out.println("Env variable fetched: "+ System.getenv("ENV_VAR_SECRET"));
182+
}
183+
}
184+
```
185+
186+
you have the following pom.xml
187+
```xml
188+
<plugins>
189+
<plugin>
190+
<groupId>org.apache.maven.plugins</groupId>
191+
<artifactId>maven-jar-plugin</artifactId>
192+
<configuration>
193+
<archive>
194+
<manifest>
195+
<addClasspath>true</addClasspath>
196+
<mainClass>org.example.Main</mainClass>
197+
</manifest>
198+
</archive>
199+
</configuration>
200+
</plugin>
201+
</plugins>
202+
```
203+
204+
This app is using some environment variables given by its execution environment
205+
when run via `java -jar myApp.jar`.
206+
207+
Now if we use the Vault Maven Plugin, we can fetch the secret, run the app via maven, and the env variable will be injected directly.
208+
By adding the followings to your pom.xml like so:
209+
```xml
210+
<plugins>
211+
<plugin>
212+
<groupId>org.apache.maven.plugins</groupId>
213+
<artifactId>maven-jar-plugin</artifactId>
214+
<configuration>
215+
<archive>
216+
<manifest>
217+
<addClasspath>true</addClasspath>
218+
<mainClass>org.example.Main</mainClass>
219+
</manifest>
220+
</archive>
221+
</configuration>
222+
</plugin>
223+
<plugin>
224+
<groupId>com.homeofthewizard</groupId>
225+
<artifactId>vault-maven-plugin</artifactId>
226+
<version>1.1.2-SNAPSHOT</version>
227+
<executions>
228+
<execution>
229+
<id>pull</id>
230+
<phase>initialize</phase>
231+
<goals>
232+
<goal>pull</goal>
233+
</goals>
234+
</execution>
235+
</executions>
236+
<configuration>
237+
<servers>
238+
<server>
239+
<url>https://your-vault-host</url>
240+
<token>XXXXX</token>
241+
<paths>
242+
<path>
243+
<name>secret/data/myJavaApp</name>
244+
<mappings>
245+
<mapping>
246+
<key>secretKey</key>
247+
<property>mavenPropertyForSecret</property>
248+
</mapping>
249+
</mappings>
250+
</path>
251+
</paths>
252+
</server>
253+
</servers>
254+
</configuration>
255+
</plugin>
256+
<plugin>
257+
<groupId>org.codehaus.mojo</groupId>
258+
<artifactId>exec-maven-plugin</artifactId>
259+
<version>1.2.1</version>
260+
<configuration>
261+
<executable>java</executable>
262+
<environmentVariables>
263+
<ENV_VAR_SECRET>${mavenPropertyForSecret}</ENV_VAR_SECRET>
264+
</environmentVariables>
265+
<arguments>
266+
<argument>-classpath</argument>
267+
<classpath />
268+
<argument>org.example.Main</argument>
269+
</arguments>
270+
</configuration>
271+
</plugin>
272+
</plugins>
273+
```
274+
And Voilà! :tada:
275+
Now you just need to run `mvn vault:pull exec:exec`
276+
The only thing to provide is the token to authenticate to Vault server (`<token>XXXXX</token>`).
277+
Isn't that magical ? :mage:
278+
279+
# 3. Application that does not use Maven
280+
Many developers use .env files to manage environment variables on their localhost.
281+
It may be the case even on production for application that do not have tools to fetch the secrets directly from a secure shared place like Vault.
282+
283+
If that is the case, the plugin can generate a .env file for you.
284+
The configuration `<outputMethod>EnvFile</outputMethod>` allows this.
285+
286+
Then you can inject it with [dotenv-java](https://github.com/cdimascio/dotenv-java) for example.
287+
288+
There are also IntelliJ plugins that help you inject secrets via .env files before running/debugging the application in your local environment.

0 commit comments

Comments
 (0)