Hi @ansgarm ,
Thank you for your assistance. I have implemented your suggestion, but I am still encountering an issue:
echo "$local.vpc0_subnet1_asg1_0_provisioning-key-stack-vpc-fdervisi-vpc1-eu-south-1_provisioning-key-string-vpc-fdervisi-vpc1-eu-south-1_11242F40"> /opt/zscaler/var/provision_key
I believe the issue may be related to how I am calling the stack. When I use Construct
,"nothing is resolved, but when I try to use TerraformStack
I receive an error. I suspect that I need to add a dependency somewhere, but I am unsure of where to add it.
Error: Usage Error: The following dependencies are not included in the stacks to run: aws-eu-south-1/vpc0/subnet1/asg1_0/provisioning-key-stack-vpc-fdervisi-vpc1-eu-south-1. Either add them or add the --ignore-missing-stack-dependencies flag.
Below is the relevant code. Perhaps you can help me identify the issue.
import { Construct } from 'constructs';
import {
appConnectorGroup,
provisioningKey,
Region,
Vpc as IVpc,
} from './CloudServiceTreeInterface';
import { AppConnectorGroup } from '../.gen/providers/zpa/app-connector-group';
import { ProvisioningKey } from '../.gen/providers/zpa/provisioning-key';
import { DataZpaEnrollmentCert } from '../.gen/providers/zpa/data-zpa-enrollment-cert';
import { DataZpaProvisioningKey } from '../.gen/providers/zpa/data-zpa-provisioning-key';
import { ZpaProvider } from '../.gen/providers/zpa/provider';
import { TerraformLocal, TerraformOutput } from 'cdktf';
interface ZscalerProvisioningKeyStackConfig {
vpc: IVpc;
region: Region;
appConnectorGroup: appConnectorGroup;
provisioningKey: provisioningKey;
}
export class ZscalerProvisioningKeyStack extends Construct {
zpaProvisioningKey: any;
provisioningKeyData: any;
provisioningKeyOutput: any;
provisioningKeyString: TerraformLocal;
output: any;
tempKey: any;
constructor(
scope: Construct,
id: string,
config: ZscalerProvisioningKeyStackConfig
) {
super(scope, id);
new ZpaProvider(this, 'Zscaler');
const zpaEnrollmentCert = new DataZpaEnrollmentCert(
this,
`enfrollment-cert-vpc-${config.vpc.name}-${config.region.name}`,
{
name: 'Connector',
}
);
const appConnectorGroup = new AppConnectorGroup(
this,
`app-connector-group-vpc-${config.vpc.name}-${config.region.name}`,
{
latitude: config.appConnectorGroup.latitude,
location: config.appConnectorGroup.location,
name: config.appConnectorGroup.name,
longitude: config.appConnectorGroup.longitude,
versionProfileName: config.appConnectorGroup.versionProfileName,
cityCountry: config.appConnectorGroup.cityCountry || undefined,
countryCode: config.appConnectorGroup.countryCode || undefined,
dnsQueryType: config.appConnectorGroup.dnsQueryType || undefined,
overrideVersionProfile:
config.appConnectorGroup.overrideVersionProfile || undefined,
}
);
this.zpaProvisioningKey = new ProvisioningKey(
this,
`zpa-provisioning-key-vpc-${config.vpc.name}-${config.region.name}`,
{
maxUsage: config.provisioningKey.maxUsage,
name: config.provisioningKey.name,
associationType: config.provisioningKey.associationType,
enrollmentCertId: zpaEnrollmentCert.id,
zcomponentId: appConnectorGroup.id,
dependsOn: [appConnectorGroup],
}
);
this.provisioningKeyData = new DataZpaProvisioningKey(
this,
`data-provisioning-key-vpc-${config.vpc.name}-${config.region.name}`,
{
name: this.zpaProvisioningKey.name,
associationType: config.provisioningKey.associationType,
}
);
this.provisioningKeyString = new TerraformLocal(
this,
`provisioning-key-string-vpc-${config.vpc.name}-${config.region.name}`,
this.provisioningKeyData.provisioningKey
);
this.output = new TerraformOutput(this, `output`, {
value: this.provisioningKeyString,
});
}
get provisioningKey(): string {
return this.provisioningKeyString.asString;
}
// set provisioningKey(provisioningKey) {
// this.provisioningKeyString.asString = provisioningKey;
// }
}
and this is the parent class where the stack is being called:
import { AutoscalingGroup } from '@cdktf/provider-aws/lib/autoscaling-group';
import { AutoscalingPolicy } from '@cdktf/provider-aws/lib/autoscaling-policy';
import { DataAwsAmi } from '@cdktf/provider-aws/lib/data-aws-ami';
import { LaunchTemplate } from '@cdktf/provider-aws/lib/launch-template';
import { Fn } from 'cdktf';
import { Construct } from 'constructs';
import * as fs from 'fs';
import { renderTemplate } from './render-template';
import { File } from '@cdktf/provider-local/lib/file';
import { LocalProvider } from '@cdktf/provider-local/lib/provider';
import {
IAsg,
// INics,
// Instance as IInstance, // interface for a Instance object
Region,
Vpc,
} from './CloudServiceTreeInterface';
import { SecurityGroup } from '@cdktf/provider-aws/lib/security-group';
import { ZscalerProvisioningKeyStack } from './zpa-provisionin-key-stack';
interface AwsAutoScalingGroupStackConfig {
autoScalingGroup: IAsg;
subnetIndex: number;
region: Region;
subnetId: string;
asgIndex: number;
vpcId: string;
vpc: Vpc;
}
interface DataAwsAmiFilterProps {
name: string;
values: string[];
}
export class AwsAutoScalingGroupStack extends Construct {
instance: any;
temp: any;
securityGroup: any;
amiFilterProps: DataAwsAmiFilterProps[] = [];
// launchTemplate: LaunchTemplate={};
nicList: any[] = [];
provisioningKey: any;
renderedTemplate: any;
zpaProvisioningKey: any;
zpaProvisioningKeyObject: { provisioning_key: string } = {
provisioning_key: '',
};
constructor(
scope: Construct,
id: string,
config: AwsAutoScalingGroupStackConfig
) {
super(scope, id);
if (config.autoScalingGroup.zpa) {
if (config.vpc.appConnector) {
this.provisioningKey = new ZscalerProvisioningKeyStack(
this,
`provisioning-key-stack-vpc-${config.vpc.name}-${config.region.name}`,
{
appConnectorGroup: config.vpc.appConnector.appConnectorGroup,
vpc: config.vpc,
provisioningKey: config.vpc.appConnector.provisioningKey,
region: config.region,
}
);
// const testTemplate = fs.readFileSync(
// `user_data/${config.autoScalingGroup.userDataTemplate}`,
// 'utf-8'
// );
// this.provisioningKey.output.value
const testTemplate = `echo "${this.provisioningKey.provisioningKey}"> /opt/zscaler/var/provision_key`;
// Initialize the local provider
new LocalProvider(this, 'local');
new File(this, 'UserDataFile', {
content: testTemplate,
filename: '../../../user_data.txt',
});
//this.renderedTemplate = fs.readFileSync('user_data.txt', 'utf8');
// const testLocal = new TerraformLocal(
// this,
// `user-data-asg-${config.asgIndex}`,
// `echo "${this.provisioningKey.provisioningKeyString}"> /opt/zscaler/var/provision_key`
// );
//console.log(testLocal);
this.renderedTemplate = `echo "${this.provisioningKey.provisioningKey}"> /opt/zscaler/var/provision_key`;
console.log('********************* renderTemplate ******************');
console.log(this.renderedTemplate);
console.log('********************* renderTemplate ******************');
//new TerraformOutput(this, 'test', { value: testLocal });
}
}
// search for AMI with Filter
const amiFilter = new DataAwsAmi(
this,
`ami${config.subnetIndex}${config.asgIndex}`,
{
filter: this.amiFilterProps,
mostRecent: config.autoScalingGroup.amiFilter?.mostRecent,
owners: config.autoScalingGroup.amiFilter?.owners || undefined,
}
);
if (config.autoScalingGroup.userDataTemplate) {
// Set default value for userDataVars if it is not provided
const userDataVars = config.autoScalingGroup.userDataVars || {};
// Read the contents of the specified user data template file
const templateString = fs.readFileSync(
`user_data/${config.autoScalingGroup.userDataTemplate}`,
'utf-8'
);
// Render the template with the given variables
// this.renderedTemplate = 'TESET';
if (!config.autoScalingGroup.zpa) {
this.renderedTemplate = renderTemplate(templateString, userDataVars);
}
// Set the rendered template as the user data for the instance
config.autoScalingGroup.userData = Fn.base64encode(
//Fn.rawString(this.renderedTemplate)
Fn.rawString(this.renderedTemplate)
);
}
<-- snip -->
}
}