├── .gitignore
├── LICENSE
├── README.md
├── SECURITY.md
├── pom.xml
├── terraform-client
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── microsoft
│ └── terraform
│ ├── ProcessLauncher.java
│ ├── TerraformClient.java
│ └── TerraformOptions.java
├── terraform-spring-boot-autoconfigure
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── microsoft
│ │ └── terraform
│ │ └── spring
│ │ └── autoconfigure
│ │ ├── TerraformAutoConfiguration.java
│ │ └── TerraformProperties.java
│ └── resources
│ └── META-INF
│ └── spring.factories
├── terraform-spring-boot-samples
├── pom.xml
├── raw-client-library-sample
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── microsoft
│ │ └── samples
│ │ └── RawClientLibSampleApp.java
├── spring-starter-sample
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── microsoft
│ │ │ └── samples
│ │ │ └── SpringStarterSampleApp.java
│ │ └── resources
│ │ └── application.properties
└── terraform
│ └── storage.tf
└── terraform-spring-boot-starter
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | # Maven Compiled Results
25 | target/
26 |
27 | # VSCode Eclipse IntelliJ
28 | *.project
29 | *.classpath
30 | *.iml
31 | .settings/
32 | .idea/
33 | .vscode/
34 |
35 | # Terraform
36 | *.tfstate
37 | *.tfstate.backup
38 | .terraform/
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Terraform Spring Boot
3 |
4 | ## Introduction
5 |
6 | This repository is for Spring Boot Starters of Terraform client.
7 |
8 | ## How to use it
9 |
10 | There are two ways you could use this library. One way is to directly use the `TerraformClient` class which wraps the `terraform` executable on your local machine; and the other way is to integrate it into a Spring boot application using annotations.
11 |
12 | ### Client library
13 |
14 | Simply add the following dependency to your project's `pom.xml` will enable you to use the `TerraformClient` class.
15 |
16 | ```xml
17 |
18 | com.microsoft.terraform
19 | terraform-client
20 | 1.0.0
21 |
22 | ```
23 |
24 | And now you are able to provision terraform resources in your Java application. Make sure you have already put a terraform file `storage.tf` under `/some/local/path/` folder; and then use the Java code snippet below to invoke `terraform` executable operate on the resources defined in `storage.tf`. In this example, we also assume that you are provisioning Azure specific resource, which means you need to set some Azure related credentials.
25 |
26 | ```java
27 | TerraformOptions options = new TerraformOptions();
28 | options.setArmSubscriptionId("");
29 | options.setArmClientId("");
30 | options.setArmClientSecret("");
31 | options.setArmTenantId("");
32 |
33 | try (TerraformClient client = new TerraformClient(options)) {
34 | client.setOutputListener(System.out::println);
35 | client.setErrorListener(System.err::println);
36 |
37 | client.setWorkingDirectory("/some/local/path/");
38 | client.plan().get();
39 | client.apply().get();
40 | }
41 | ```
42 |
43 | ### Spring boot
44 |
45 | Let's still use the terraform file `storage.tf` under `/some/local/path/` folder to provision Azure resources in this example. Rather than create the `TerraformClient` by ourselves, we let the spring boot framework to wire it for us. First add the following dependency to your `pom.xml`:
46 |
47 | ```xml
48 |
49 | com.microsoft.terraform
50 | terraform-spring-boot-starter
51 | 1.0.0
52 |
53 | ```
54 |
55 | And now let's also introduce the Azure credentials in `application.properties`:
56 |
57 | ```
58 | terraform.armSubscriptionId=
59 | terraform.armClientId=
60 | terraform.armClientSecret=
61 | terraform.armTenantId=
62 | ```
63 |
64 | The final step is to let the Spring framework wire up everything in your spring boot application:
65 |
66 | ```java
67 | @SpringBootApplication
68 | public class SpringStarterSampleApp implements CommandLineRunner {
69 | public static void main(String[] args) {
70 | SpringApplication.run(SpringStarterSampleApp.class, args);
71 | }
72 |
73 | @Autowired
74 | private TerraformClient terraform;
75 |
76 | @Override
77 | public void run(String... args) throws Exception {
78 | try {
79 | this.terraform.setOutputListener(System.out::println);
80 | this.terraform.setErrorListener(System.err::println);
81 |
82 | this.terraform.setWorkingDirectory("/some/local/path/");
83 | this.terraform.plan().get();
84 | this.terraform.apply().get();
85 | } finally {
86 | this.terraform.close();
87 | }
88 | }
89 | }
90 | ```
91 |
92 |
93 | ## Contributing
94 |
95 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
96 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
97 | the rights to use your contribution. For details, visit https://cla.microsoft.com.
98 |
99 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
100 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
101 | provided by the bot. You will only need to do this once across all repos using our CLA.
102 |
103 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
104 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
105 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
106 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.microsoft.terraform
5 | terraform-spring-boot-solution
6 | 1.0.0
7 | pom
8 |
9 | Terraform Spring Boot solution
10 | https://github.com/Microsoft/terraform-spring-boot
11 |
12 |
13 | UTF-8
14 |
15 |
16 |
17 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
18 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
19 | https://github.com/Microsoft/terraform-spring-boot/tree/master
20 |
21 |
22 |
23 |
24 | MIT
25 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
26 | repo
27 |
28 |
29 |
30 |
31 | Microsoft
32 | https://www.microsoft.com
33 |
34 |
35 |
36 |
37 | JunyiYi
38 | Junyi Yi
39 | junyi@microsoft.com
40 |
41 |
42 |
43 |
44 | terraform-client
45 | terraform-spring-boot-autoconfigure
46 | terraform-spring-boot-starter
47 | terraform-spring-boot-samples
48 |
49 |
50 |
--------------------------------------------------------------------------------
/terraform-client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.microsoft.terraform
5 | terraform-client
6 | 1.0.0
7 | jar
8 |
9 | Terraform Client for Java developers
10 | Terraform client wrapper for Java developers
11 | https://github.com/Microsoft/terraform-spring-boot
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
19 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
20 | https://github.com/Microsoft/terraform-spring-boot/tree/master
21 |
22 |
23 |
24 |
25 | MIT
26 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
27 | repo
28 |
29 |
30 |
31 |
32 | Microsoft
33 | https://www.microsoft.com
34 |
35 |
36 |
37 |
38 | JunyiYi
39 | Junyi Yi
40 | junyi@microsoft.com
41 |
42 |
43 |
44 |
45 |
46 |
47 | maven-compiler-plugin
48 | 3.7.0
49 |
50 | 1.8
51 | 1.8
52 |
53 |
54 |
55 | org.apache.maven.plugins
56 | maven-source-plugin
57 | 3.0.1
58 |
59 |
60 | attach-sources
61 |
62 | jar
63 |
64 |
65 |
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-javadoc-plugin
70 | 3.0.0
71 |
72 |
73 | attach-javadocs
74 |
75 | jar
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/terraform-client/src/main/java/com/microsoft/terraform/ProcessLauncher.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.terraform;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 | import java.util.concurrent.*;
6 | import java.util.function.*;
7 | import java.util.stream.*;
8 |
9 | final class ProcessLauncher {
10 | private Process process;
11 | private ProcessBuilder builder;
12 | private Consumer outputListener, errorListener;
13 | private boolean inheritIO;
14 | private ExecutorService executor;
15 |
16 | ProcessLauncher(ExecutorService executor, String... commands) {
17 | assert executor != null;
18 | this.executor = executor;
19 | this.process = null;
20 | this.builder = new ProcessBuilder(commands);
21 | }
22 |
23 | void setOutputListener(Consumer listener) {
24 | assert this.process == null;
25 | this.outputListener = listener;
26 | }
27 |
28 | void setErrorListener(Consumer listener) {
29 | assert this.process == null;
30 | this.errorListener = listener;
31 | }
32 |
33 | void setInheritIO(boolean inheritIO) {
34 | assert this.process == null;
35 | this.inheritIO = inheritIO;
36 | }
37 |
38 | void setDirectory(File directory) {
39 | assert this.process == null;
40 | this.builder.directory(directory);
41 | }
42 |
43 | void appendCommands(String... commands) {
44 | Stream filteredCommands = Arrays.stream(commands).filter(c -> c != null && c.length() > 0);
45 | this.builder.command().addAll(filteredCommands.collect(Collectors.toList()));
46 | }
47 |
48 | void setEnvironmentVariable(String name, String value) {
49 | assert name != null && name.length() > 0;
50 | Map env = this.builder.environment();
51 | value = (value != null ? env.put(name, value) : env.remove(name));
52 | }
53 |
54 | void setOrAppendEnvironmentVariable(String name, String value, String delimiter) {
55 | assert name != null && name.length() > 0;
56 | if (value != null && value.length() > 0) {
57 | String current = System.getenv(name);
58 | String target = (current == null || current.length() == 0 ? value : String.join(delimiter, current, value));
59 | this.setEnvironmentVariable(name, target);
60 | }
61 | }
62 |
63 | CompletableFuture launch() {
64 | assert this.process == null;
65 | if (this.inheritIO) {
66 | this.builder.inheritIO();
67 | }
68 | try {
69 | this.process = this.builder.start();
70 | } catch (IOException ex) {
71 | throw new RuntimeException(ex);
72 | }
73 | if (!this.inheritIO) {
74 | if (this.outputListener != null) {
75 | this.executor.submit(() -> this.readProcessStream(this.process.getInputStream(), this.outputListener));
76 | }
77 | if (this.errorListener != null) {
78 | this.executor.submit(() -> this.readProcessStream(this.process.getErrorStream(), this.errorListener));
79 | }
80 | }
81 | return CompletableFuture.supplyAsync(() -> {
82 | try {
83 | return this.process.waitFor();
84 | } catch (InterruptedException ex) {
85 | throw new RuntimeException(ex);
86 | }
87 | }, this.executor);
88 | }
89 |
90 | private boolean readProcessStream(InputStream stream, Consumer listener) {
91 | try {
92 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
93 | String line;
94 | while ((line = reader.readLine()) != null) {
95 | listener.accept(line);
96 | }
97 | }
98 | return true;
99 | } catch (IOException ex) {
100 | return false;
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/terraform-client/src/main/java/com/microsoft/terraform/TerraformClient.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.terraform;
2 |
3 | import java.io.*;
4 | import java.nio.file.*;
5 | import java.util.*;
6 | import java.util.concurrent.*;
7 | import java.util.function.*;
8 |
9 | public class TerraformClient implements AutoCloseable {
10 | private static final String TERRAFORM_EXE_NAME = "terraform";
11 | private static final String VERSION_COMMAND = "version", INIT_COMMAND = "init", PLAN_COMMAND = "plan", APPLY_COMMAND = "apply", DESTROY_COMMAND = "destroy";
12 | private static final String SUBS_ID_ENV_NAME = "ARM_SUBSCRIPTION_ID", CLIENT_ID_ENV_NAME = "ARM_CLIENT_ID", SECRET_ENV_NAME = "ARM_CLIENT_SECRET", TENANT_ID_ENV_NAME = "ARM_TENANT_ID";
13 | private static final String USER_AGENT_ENV_NAME = "AZURE_HTTP_USER_AGENT", USER_AGENT_ENV_VALUE = "Java-TerraformClient", USER_AGENT_DELIMITER = ";";
14 | private static final Map NON_INTERACTIVE_COMMAND_MAP = new HashMap<>();
15 | static {
16 | NON_INTERACTIVE_COMMAND_MAP.put(APPLY_COMMAND, "-auto-approve");
17 | NON_INTERACTIVE_COMMAND_MAP.put(DESTROY_COMMAND, "-force");
18 | }
19 |
20 | private final ExecutorService executor = Executors.newWorkStealingPool();
21 | private final TerraformOptions options;
22 | private File workingDirectory;
23 | private boolean inheritIO;
24 | private Consumer outputListener, errorListener;
25 |
26 | public TerraformClient() {
27 | this(new TerraformOptions());
28 | }
29 |
30 | public TerraformClient(TerraformOptions options) {
31 | assert options != null;
32 | this.options = options;
33 | }
34 |
35 | public Consumer getOutputListener() {
36 | return this.outputListener;
37 | }
38 |
39 | public void setOutputListener(Consumer listener) {
40 | this.outputListener = listener;
41 | }
42 |
43 | public Consumer getErrorListener() {
44 | return this.errorListener;
45 | }
46 |
47 | public void setErrorListener(Consumer listener) {
48 | this.errorListener = listener;
49 | }
50 |
51 | public File getWorkingDirectory() {
52 | return workingDirectory;
53 | }
54 |
55 | public void setWorkingDirectory(File workingDirectory) {
56 | this.workingDirectory = workingDirectory;
57 | }
58 |
59 | public void setWorkingDirectory(Path folderPath) {
60 | this.setWorkingDirectory(folderPath.toFile());
61 | }
62 |
63 | public boolean isInheritIO() {
64 | return this.inheritIO;
65 | }
66 |
67 | public void setInheritIO(boolean inheritIO) {
68 | this.inheritIO = inheritIO;
69 | }
70 |
71 | public CompletableFuture version() throws IOException {
72 | ProcessLauncher launcher = this.getTerraformLauncher(VERSION_COMMAND);
73 | StringBuilder version = new StringBuilder();
74 | Consumer outputListener = this.getOutputListener();
75 | launcher.setOutputListener(m -> {
76 | version.append(version.length() == 0 ? m : "");
77 | if (outputListener != null) {
78 | outputListener.accept(m);
79 | }
80 | });
81 | return launcher.launch().thenApply((c) -> c == 0 ? version.toString() : null);
82 | }
83 |
84 | public CompletableFuture plan() throws IOException {
85 | this.checkRunningParameters();
86 | return this.run(INIT_COMMAND, PLAN_COMMAND);
87 | }
88 |
89 | public CompletableFuture apply() throws IOException {
90 | this.checkRunningParameters();
91 | return this.run(INIT_COMMAND, APPLY_COMMAND);
92 | }
93 |
94 | public CompletableFuture destroy() throws IOException {
95 | this.checkRunningParameters();
96 | return this.run(INIT_COMMAND, DESTROY_COMMAND);
97 | }
98 |
99 | private CompletableFuture run(String... commands) throws IOException {
100 | assert commands.length > 0;
101 | ProcessLauncher[] launchers = new ProcessLauncher[commands.length];
102 | for (int i = 0; i < commands.length; i++) {
103 | launchers[i] = this.getTerraformLauncher(commands[i]);
104 | }
105 |
106 | CompletableFuture result = launchers[0].launch().thenApply(c -> c == 0 ? 1 : -1);
107 | for (int i = 1; i < commands.length; i++) {
108 | result = result.thenCompose(index -> {
109 | if (index > 0) {
110 | return launchers[index].launch().thenApply(c -> c == 0 ? index + 1 : -1);
111 | }
112 | return CompletableFuture.completedFuture(-1);
113 | });
114 | }
115 | return result.thenApply(i -> i > 0);
116 | }
117 |
118 | private void checkRunningParameters() {
119 | if (this.getWorkingDirectory() == null) {
120 | throw new IllegalArgumentException("working directory should not be null");
121 | }
122 | }
123 |
124 | private ProcessLauncher getTerraformLauncher(String command) throws IOException {
125 | ProcessLauncher launcher = new ProcessLauncher(this.executor, TERRAFORM_EXE_NAME, command);
126 | launcher.setDirectory(this.getWorkingDirectory());
127 | launcher.setInheritIO(this.isInheritIO());
128 | launcher.setOrAppendEnvironmentVariable(USER_AGENT_ENV_NAME, USER_AGENT_ENV_VALUE, USER_AGENT_DELIMITER);
129 | launcher.setEnvironmentVariable(SUBS_ID_ENV_NAME, this.options.getArmSubscriptionId());
130 | launcher.setEnvironmentVariable(CLIENT_ID_ENV_NAME, this.options.getArmClientId());
131 | launcher.setEnvironmentVariable(SECRET_ENV_NAME, this.options.getArmClientSecret());
132 | launcher.setEnvironmentVariable(TENANT_ID_ENV_NAME, this.options.getArmTenantId());
133 | launcher.appendCommands(NON_INTERACTIVE_COMMAND_MAP.get(command));
134 | launcher.setOutputListener(this.getOutputListener());
135 | launcher.setErrorListener(this.getErrorListener());
136 | return launcher;
137 | }
138 |
139 | @Override
140 | public void close() throws Exception {
141 | this.executor.shutdownNow();
142 | if (!this.executor.awaitTermination(5, TimeUnit.SECONDS)) {
143 | throw new RuntimeException("executor did not terminate");
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/terraform-client/src/main/java/com/microsoft/terraform/TerraformOptions.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.terraform;
2 |
3 | public class TerraformOptions {
4 | private String armSubscriptionId, armClientId, armClientSecret, armTenantId;
5 |
6 | public String getArmSubscriptionId() {
7 | return this.armSubscriptionId;
8 | }
9 |
10 | public void setArmSubscriptionId(String armSubscriptionId) {
11 | this.armSubscriptionId = armSubscriptionId;
12 | }
13 |
14 | public String getArmClientId() {
15 | return this.armClientId;
16 | }
17 |
18 | public void setArmClientId(String armClientId) {
19 | this.armClientId = armClientId;
20 | }
21 |
22 | public String getArmClientSecret() {
23 | return this.armClientSecret;
24 | }
25 |
26 | public void setArmClientSecret(String armClientSecret) {
27 | this.armClientSecret = armClientSecret;
28 | }
29 |
30 | public String getArmTenantId() {
31 | return this.armTenantId;
32 | }
33 |
34 | public void setArmTenantId(String armTenantId) {
35 | this.armTenantId = armTenantId;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/terraform-spring-boot-autoconfigure/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.microsoft.terraform
5 | terraform-spring-boot-autoconfigure
6 | 1.0.0
7 | jar
8 |
9 | Terraform Spring Boot Auto-configure
10 | Terraform spring boot auto-configuration.
11 | https://github.com/Microsoft/terraform-spring-boot
12 |
13 |
14 | UTF-8
15 | 1.0.0
16 | 1.5.10.RELEASE
17 |
18 |
19 |
20 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
21 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
22 | https://github.com/Microsoft/terraform-spring-boot/tree/master
23 |
24 |
25 |
26 |
27 | MIT
28 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
29 | repo
30 |
31 |
32 |
33 |
34 | Microsoft
35 | https://www.microsoft.com
36 |
37 |
38 |
39 |
40 | JunyiYi
41 | Junyi Yi
42 | junyi@microsoft.com
43 |
44 |
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot
50 | ${springboot.version}
51 |
52 |
53 |
54 | org.springframework.boot
55 | spring-boot-autoconfigure
56 | ${springboot.version}
57 |
58 |
59 |
60 | org.springframework.boot
61 | spring-boot-configuration-processor
62 | ${springboot.version}
63 | true
64 |
65 |
66 |
67 | com.microsoft.terraform
68 | terraform-client
69 | ${azterraform.version}
70 |
71 |
72 |
73 |
74 |
75 |
76 | maven-compiler-plugin
77 | 3.7.0
78 |
79 | 1.8
80 | 1.8
81 |
82 |
83 |
84 | org.apache.maven.plugins
85 | maven-source-plugin
86 | 3.0.1
87 |
88 |
89 | attach-sources
90 |
91 | jar
92 |
93 |
94 |
95 |
96 |
97 | org.apache.maven.plugins
98 | maven-javadoc-plugin
99 | 3.0.0
100 |
101 |
102 | attach-javadocs
103 |
104 | jar
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/terraform-spring-boot-autoconfigure/src/main/java/com/microsoft/terraform/spring/autoconfigure/TerraformAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.terraform.spring.autoconfigure;
2 |
3 | import org.springframework.boot.autoconfigure.condition.*;
4 | import org.springframework.boot.context.properties.*;
5 | import org.springframework.context.annotation.*;
6 |
7 | import com.microsoft.terraform.*;
8 |
9 | @Configuration
10 | @EnableConfigurationProperties(TerraformProperties.class)
11 | @ConditionalOnMissingBean(TerraformClient.class)
12 | public class TerraformAutoConfiguration {
13 | private TerraformProperties tfProperties;
14 |
15 | public TerraformAutoConfiguration(TerraformProperties properties) {
16 | assert properties != null;
17 | this.tfProperties = properties;
18 | }
19 |
20 | @Bean
21 | public TerraformClient terraformClient() {
22 | TerraformOptions tfOptions = new TerraformOptions();
23 | tfOptions.setArmSubscriptionId(this.tfProperties.getArmSubscriptionId());
24 | tfOptions.setArmClientId(this.tfProperties.getArmClientId());
25 | tfOptions.setArmClientSecret(this.tfProperties.getArmClientSecret());
26 | tfOptions.setArmTenantId(this.tfProperties.getArmTenantId());
27 | return new TerraformClient(tfOptions);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/terraform-spring-boot-autoconfigure/src/main/java/com/microsoft/terraform/spring/autoconfigure/TerraformProperties.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.terraform.spring.autoconfigure;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 |
5 | @ConfigurationProperties("terraform")
6 | public class TerraformProperties {
7 | private String armSubscriptionId, armClientId, armClientSecret, armTenantId;
8 |
9 | public String getArmSubscriptionId() {
10 | return this.armSubscriptionId;
11 | }
12 |
13 | public void setArmSubscriptionId(String armSubscriptionId) {
14 | this.armSubscriptionId = armSubscriptionId;
15 | }
16 |
17 | public String getArmClientId() {
18 | return this.armClientId;
19 | }
20 |
21 | public void setArmClientId(String armClientId) {
22 | this.armClientId = armClientId;
23 | }
24 |
25 | public String getArmClientSecret() {
26 | return this.armClientSecret;
27 | }
28 |
29 | public void setArmClientSecret(String armClientSecret) {
30 | this.armClientSecret = armClientSecret;
31 | }
32 |
33 | public String getArmTenantId() {
34 | return this.armTenantId;
35 | }
36 |
37 | public void setArmTenantId(String armTenantId) {
38 | this.armTenantId = armTenantId;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/terraform-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | com.microsoft.terraform.spring.autoconfigure.TerraformAutoConfiguration
3 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.microsoft.terraform.samples
5 | terraform-spring-boot-samples-solution
6 | 1.0.0
7 | pom
8 |
9 | Terraform Spring Boot samples solution
10 | https://github.com/Microsoft/terraform-spring-boot
11 |
12 |
13 | UTF-8
14 |
15 |
16 |
17 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
18 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
19 | https://github.com/Microsoft/terraform-spring-boot/tree/master
20 |
21 |
22 |
23 |
24 | MIT
25 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
26 | repo
27 |
28 |
29 |
30 |
31 | Microsoft
32 | https://www.microsoft.com
33 |
34 |
35 |
36 |
37 | JunyiYi
38 | Junyi Yi
39 | junyi@microsoft.com
40 |
41 |
42 |
43 |
44 | raw-client-library-sample
45 | spring-starter-sample
46 |
47 |
48 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/raw-client-library-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.microsoft.terraform.samples
6 | terraform-raw-client-lib
7 | 1.0.0
8 | jar
9 |
10 | Using raw Terraform client library sample
11 | https://github.com/Microsoft/terraform-spring-boot
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
19 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
20 | https://github.com/Microsoft/terraform-spring-boot/tree/master
21 |
22 |
23 |
24 |
25 | MIT
26 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
27 | repo
28 |
29 |
30 |
31 |
32 | Microsoft
33 | https://www.microsoft.com
34 |
35 |
36 |
37 |
38 | JunyiYi
39 | Junyi Yi
40 | junyi@microsoft.com
41 |
42 |
43 |
44 |
45 |
46 | com.microsoft.terraform
47 | terraform-client
48 | 1.0.0
49 |
50 |
51 |
52 |
53 |
54 |
55 | maven-compiler-plugin
56 | 3.7.0
57 |
58 | 1.8
59 | 1.8
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/raw-client-library-sample/src/main/java/com/microsoft/samples/RawClientLibSampleApp.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.samples;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 |
6 | import com.microsoft.terraform.*;
7 |
8 | public final class RawClientLibSampleApp {
9 | public static void main(String[] args) throws Exception {
10 | if (args.length != 1) {
11 | System.out.println("Working folder path argument missing");
12 | System.exit(1);
13 | }
14 | TerraformOptions options = new TerraformOptions();
15 | options.setArmSubscriptionId("");
16 | options.setArmClientId("");
17 | options.setArmClientSecret("");
18 | options.setArmTenantId("");
19 | try (TerraformClient client = new TerraformClient(options)) {
20 | System.out.println(client.version().get());
21 | client.setOutputListener(System.out::println);
22 | client.setErrorListener(System.err::println);
23 |
24 | client.setWorkingDirectory(new File(args[0]));
25 |
26 | Scanner input = new Scanner(System.in);
27 | System.out.print("Enter 'Y' to plan: ");
28 | if (!input.next().equalsIgnoreCase("Y")) {
29 | return;
30 | }
31 | System.out.println(client.plan().get());
32 | System.out.print("Enter 'Y' to apply: ");
33 | if (!input.next().equalsIgnoreCase("Y")) {
34 | return;
35 | }
36 | System.out.println(client.apply().get());
37 | System.out.print("Enter 'Y' to destroy: ");
38 | if (!input.next().equalsIgnoreCase("Y")) {
39 | return;
40 | }
41 | System.out.println(client.destroy().get());
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/spring-starter-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.microsoft.terraform.samples
6 | terraform-spring-starter
7 | 1.0.0
8 | jar
9 |
10 | Terraform Spring Boot Starter Sample App
11 | https://github.com/Microsoft/terraform-spring-boot
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-parent
16 | 1.5.10.RELEASE
17 |
18 |
19 |
20 | UTF-8
21 |
22 |
23 |
24 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
25 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
26 | https://github.com/Microsoft/terraform-spring-boot/tree/master
27 |
28 |
29 |
30 |
31 | MIT
32 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
33 | repo
34 |
35 |
36 |
37 |
38 | Microsoft
39 | https://www.microsoft.com
40 |
41 |
42 |
43 |
44 | JunyiYi
45 | Junyi Yi
46 | junyi@microsoft.com
47 |
48 |
49 |
50 |
51 |
52 | com.microsoft.terraform
53 | terraform-spring-boot-starter
54 | 1.0.0
55 |
56 |
57 |
58 |
59 |
60 |
61 | maven-compiler-plugin
62 | 3.7.0
63 |
64 | 1.8
65 | 1.8
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/spring-starter-sample/src/main/java/com/microsoft/samples/SpringStarterSampleApp.java:
--------------------------------------------------------------------------------
1 | package com.microsoft.samples;
2 |
3 | import java.io.*;
4 | import java.util.*;
5 |
6 | import com.microsoft.terraform.*;
7 |
8 | import org.springframework.beans.factory.annotation.*;
9 | import org.springframework.boot.*;
10 | import org.springframework.boot.autoconfigure.*;
11 |
12 | @SpringBootApplication
13 | public class SpringStarterSampleApp implements CommandLineRunner {
14 | public static void main(String[] args) {
15 | SpringApplication.run(SpringStarterSampleApp.class, args);
16 | }
17 |
18 | @Autowired
19 | private TerraformClient terraform;
20 |
21 | @Override
22 | public void run(String... args) throws Exception {
23 | if (args.length != 1) {
24 | System.out.println("Working folder path argument missing");
25 | System.exit(1);
26 | }
27 |
28 | try {
29 | System.out.println(this.terraform.version().get());
30 |
31 | this.terraform.setOutputListener(System.out::println);
32 | this.terraform.setErrorListener(System.err::println);
33 | this.terraform.setWorkingDirectory(new File(args[0]));
34 |
35 | Scanner input = new Scanner(System.in);
36 | System.out.print("Enter 'Y' to plan: ");
37 | if (!input.next().equalsIgnoreCase("Y")) {
38 | return;
39 | }
40 | System.out.println(this.terraform.plan().get());
41 | System.out.print("Enter 'Y' to apply: ");
42 | if (!input.next().equalsIgnoreCase("Y")) {
43 | return;
44 | }
45 | System.out.println(this.terraform.apply().get());
46 | System.out.print("Enter 'Y' to destroy: ");
47 | if (!input.next().equalsIgnoreCase("Y")) {
48 | return;
49 | }
50 | System.out.println(this.terraform.destroy().get());
51 | } finally {
52 | this.terraform.close();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/spring-starter-sample/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | terraform.armSubscriptionId=
2 | terraform.armClientId=
3 | terraform.armClientSecret=
4 | terraform.armTenantId=
5 |
--------------------------------------------------------------------------------
/terraform-spring-boot-samples/terraform/storage.tf:
--------------------------------------------------------------------------------
1 | resource "azurerm_resource_group" "rg" {
2 | name = "tfclienttestrg"
3 | location = "westus2"
4 | }
5 |
6 | resource "azurerm_storage_account" "testsa" {
7 | name = "tfclienttestsa"
8 | resource_group_name = "${azurerm_resource_group.rg.name}"
9 | location = "${azurerm_resource_group.rg.location}"
10 | account_tier = "Standard"
11 | account_replication_type = "GRS"
12 | }
13 |
--------------------------------------------------------------------------------
/terraform-spring-boot-starter/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | com.microsoft.terraform
5 | terraform-spring-boot-starter
6 | 1.0.0
7 |
8 | Terraform Spring Boot Starter
9 | Terraform starter, including auto-configuration support.
10 | https://github.com/Microsoft/terraform-spring-boot
11 |
12 |
13 | scm:git:git://github.com/Microsoft/terraform-spring-boot.git
14 | scm:git:ssh://github.com:Microsoft/terraform-spring-boot.git
15 | https://github.com/Microsoft/terraform-spring-boot/tree/master
16 |
17 |
18 |
19 |
20 | MIT
21 | https://github.com/Microsoft/terraform-spring-boot/blob/master/LICENSE
22 | repo
23 |
24 |
25 |
26 |
27 | Microsoft
28 | https://www.microsoft.com
29 |
30 |
31 |
32 |
33 | JunyiYi
34 | Junyi Yi
35 | junyi@microsoft.com
36 |
37 |
38 |
39 |
40 | UTF-8
41 | 1.0.0
42 | 1.5.10.RELEASE
43 |
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter
49 | ${springboot.version}
50 |
51 |
52 |
53 | com.microsoft.terraform
54 | terraform-spring-boot-autoconfigure
55 | ${azterraform.version}
56 |
57 |
58 |
59 | com.microsoft.terraform
60 | terraform-client
61 | ${azterraform.version}
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-source-plugin
70 | 3.0.1
71 |
72 |
73 | attach-sources
74 |
75 | jar
76 |
77 |
78 |
79 |
80 |
81 | org.apache.maven.plugins
82 | maven-javadoc-plugin
83 | 3.0.0
84 |
85 |
86 | attach-javadocs
87 |
88 | jar
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------