Build and Run the jar of terraform CDK

Hey,

I’m beginner to Terraform CDK. I’ve created simple code in terraform CDK to create an EC2 instance. but here instead of run cdktf deploy in terminal I’m calling is via java processbuilder inside my main method.

Every thing good till now. My Code is compile successful and Jar build. But we I run the jar by command java -jar target/<jarname> getting the below error.

└─[$] java -jar target/irm-1.0-SNAPSHOT.jar                                                                                                                       [0:24:43]
Error: Unable to initialize main class com.example.test.Main
Caused by: java.lang.NoClassDefFoundError: software/constructs/Construct

Here is the my file structure

Here is the Main.java

package com.example.test;

import com.hashicorp.cdktf.App;
import com.hashicorp.cdktf.TerraformStack;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        final App app = new App();
        TerraformStack stack = new MainStack(app, "aws_instance");
//        new RemoteBackend(stack, RemoteBackendProps.builder()
//                .hostname("app.terraform.io")
//                .organization("<YOUR_ORG>")
//                .workspaces(new NamedRemoteWorkspace("learn-cdktf"))
//                .build());

        app.synth();

        //calling cdktf deploy
        List<String> list = new ArrayList<String>();
        list.add("/usr/local/bin/cdktf");
        list.add("deploy");

        // create the process
        ProcessBuilder build = new ProcessBuilder(list);

        // starting the process
        Process process = build.start();

        // for reading the output from stream
        BufferedReader stdInput
                = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        String s = null;
        while ((s = stdInput.readLine()) != null) {
            System.out.println(s);
        }
    }
}

Here is the MainStack.java

package com.example.test;

import software.constructs.Construct;

import com.hashicorp.cdktf.TerraformStack;
import com.hashicorp.cdktf.TerraformOutput;

import com.hashicorp.cdktf.providers.aws.AwsProvider;
import com.hashicorp.cdktf.providers.aws.ec2.Instance;

public class MainStack extends TerraformStack
{
    public MainStack(final Construct scope, final String id) {
        super(scope, id);

        AwsProvider.Builder.create(this, "AWS")
                .region("ap-south-1")
                .build();

        Instance instance = Instance.Builder.create(this, "compute")
                .ami("ami-0e18b1d379af4e263")
                .instanceType("t3a.micro")
                .build();

        TerraformOutput.Builder.create(this, "public_ip")
                .value(instance.getPublicIp())
                .build();
    }
}

Hey there,

There are two problems I can spot here:

  1. The error you are getting hints towards the construct package not being installed in this project. I’d recommend using the “normal” workflow of running your cdktf program by running cdktf synth or cdktf deploy in the CLI. You can also compile your program (it it’s a standard program like we initialize it) by running mvn -e -q compile
  2. It seems like you are trying to execute deploy from within your cdktf program. This won’t work, it will create an infinite loop since this program is being run by the synth operation that is being run before the deploy executes. If you want to start cdktf programmatically it has to be from another program that is independent from you CDKTF application