How can I structure my Terraform CDK code in TypeScript to create a simple VPC using multiple files and classes for each building block? I am looking for a way to organize my code in a more modular and maintainable way.
This is my main code:
import { App } from 'cdktf'; // import the App class from the cdktf library
import { RegionStack } from './lib/region-stack'; // import the RegionStack class from the './lib/region-stack' module
// Create a new App object
const app = new App();
// Create a new RegionStack object and pass it the app object, a string identifier, and a configuration object
new RegionStack(app, `aws`, {
environment: 'dev', // field for the environment in which the region stack will be created
region: 'eu-south-1', // field for the AWS region in which the region stack will be created
});
// Synthesize the CloudFormation template for the AWS resources specified in the code
app.synth();
I will call the RegionStack class:
import { Construct } from 'constructs';
import { TerraformStack } from 'cdktf';
import { VpcStack } from './vpc-stack';
import { AwsProvider } from '@cdktf/provider-aws/lib/provider';
// Interface for the RegionStackConfig object
interface RegionStackConfig {
environment: string; // required field for the configuration object
region?: string; // optional field for the configuration object
}
// The RegionStack class represents a stack of AWS resources for creating resources in a region
export class RegionStack extends TerraformStack {
// Constructor for the RegionStack class
// - scope: the Construct object that represents the scope for the region stack
// - id: a string that is used to identify the region stack
// - config: a RegionStackConfig object that contains configuration information for the region stack
constructor(scope: Construct, id: string, config: RegionStackConfig) {
// Call the parent constructor
super(scope, id);
// Create a new AwsProvider object and pass it the region field of the config object as the region field in its configuration object
new AwsProvider(this, 'AWS', { region: config.region });
// Create a new VpcStack object and pass it a configuration object with the name, cidr_block, and environment fields
new VpcStack(this, 'test', {
name: 'test',
cidr_block: '10.0.0.0/16',
environment: config.environment,
});
}
}
and then the VpcStack class:
import { Construct } from 'constructs';
import { TerraformStack } from 'cdktf';
import { Vpc } from '@cdktf/provider-aws/lib/vpc';
// The VpcStack class represents a stack of AWS resources for creating a VPC
export class VpcStack extends TerraformStack {
// property to hold the VPC object
vpc: any;
// property to hold the Internet Gateway object
InetGw: any;
// Constructor for the VpcStack class
// - scope: the Construct object that represents the scope for the VPC stack
// - id: a string that is used to identify the VPC stack
// - config: an object that contains configuration information for the VPC stack, including the cidr_block and name fields
constructor(scope: Construct, id: string, config: any) {
// Call the parent constructor
super(scope, id);
// Create a new Vpc object and assign it to the vpc property of the VpcStack object
// The Vpc object is created with the cidr_block and enable_dns_hostnames fields from the config object
this.vpc = new Vpc(this, `vpc${config.name}`, {
cidrBlock: config.cidr_block,
enableDnsHostnames: true,
});
}
}
and this is the error what I get:
ubuntu@ip-172-31-16-130:~/CloudServiceTree$ cdktf deploy
⠴ Synthesizing
[2023-01-01T15:41:54.338] [ERROR] default - /home/ubuntu/CloudServiceTree/node_modules/cdktf/lib/terraform-stack.ts:342
throw new Error(
^
[2023-01-01T15:41:54.340] [ERROR] default - Error: Validation failed with the following errors:
[aws/test] Found resources without a matching provider construct. Please make sure to add provider constructs [e.g. new RandomProvider(...)] to your stack 'test' for the following providers: aws
at RegionStack.runAllValidations (/home/ubuntu/CloudServiceTree/node_modules/cdktf/lib/terraform-stack.ts:342:13)
at StackSynthesizer.synthesize (/home/ubuntu/CloudServiceTree/node_modules/cdktf/lib/synthesize/synthesizer.ts:30:18)
at /home/ubuntu/CloudServiceTree/node_modules/cdktf/lib/app.ts:129:49
at Array.forEach (<anonymous>)
at App.synth (/home/ubuntu/CloudServiceTree/node_modules/cdktf/lib/app.ts:129:12)
at Object.<anonymous> (/home/ubuntu/CloudServiceTree/main.ts:14:5)
at Module._compile (node:internal/modules/cjs/loader:1120:14)
at Module.m._compile (/home/ubuntu/CloudServiceTree/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (node:internal/modules/cjs/loader:1174:10)
ERROR: cdktf encountered an error while synthesizing
Synth command: npx ts-node main.ts
Error: non-zero exit code 1
Question: I am using the Terraform CDK with TypeScript and I am trying to pass the AwsProvider to my sub-classes. However, if I create an AwsProvider object in each of my sub-classes, I will end up with multiple stacks. How can I avoid this and pass the AwsProvider object to all of my sub-classes while still maintaining a clean and modular structure?