Step 4: Infrastructure as Code
This example use IaC backed component from @dinghy/tf-aws
to not only generate same diagramm as
Step 3: draw.io, but also terraform code below:
- Source
- Diagram
- Terraform Code
app.tsx
import { extendStyle, Stack } from "@dinghy/base-components";
import * as awsGeneralResources from "@dinghy/diagrams/entitiesAwsGeneralResources";
import {
PRIVATE_SUBNET,
PUBLIC_SUBNET,
} from "@dinghy/diagrams/containersAwsGroups";
import { Waf } from "@dinghy/diagrams/entitiesAwsSecurityIdentityCompliance";
import { POSTGRE_SQL_INSTANCE } from "@dinghy/diagrams/entitiesAwsDatabase";
import { AwsCloud } from "@dinghy/tf-aws/foundation";
import { AwsLb } from "@dinghy/tf-aws/serviceElbv2";
import {
AwsSubnet,
DataAwsVpc,
useAwsSubnet,
useAwsSubnets,
useAwsVpc,
} from "@dinghy/tf-aws/serviceVpc";
import { AwsInstance } from "@dinghy/tf-aws/serviceEc2";
import { AwsDbInstance } from "@dinghy/tf-aws/serviceRds";
export default function App() {
return (
<WebApp>
<Client />
<Cloud>
<PublicSubnet>
<LoadBalancer />
<Firewall />
</PublicSubnet>
<PrivateSubnet>
<Application />
<Postgres />
</PrivateSubnet>
</Cloud>
</WebApp>
);
}
const Postgres = (props: any) => (
<AwsDbInstance
instance_class="db.t3.micro"
{...props}
_style={extendStyle(props, POSTGRE_SQL_INSTANCE)}
/>
);
const WebApp = (props: any) => <Stack {...props} />;
const Client = (props: any) => (
<awsGeneralResources.Client _dependsOn="Load Balancer" {...props} />
);
const Cloud = (props: any) => (
<AwsCloud {...props} region="eu-west-1">
<DataAwsVpc _display="invisible">
{props.children}
</DataAwsVpc>
</AwsCloud>
);
const PublicSubnet = (props: any) => (
<AwsSubnet
cidr_block="10.0.0.0/16"
vpc_id={useAwsVpc().awsVpc.id}
_direction="vertical"
{...props}
_style={extendStyle(props, PUBLIC_SUBNET)}
/>
);
const PrivateSubnet = (props: any) => (
<AwsSubnet
cidr_block="10.10.0.0/16"
vpc_id={useAwsVpc().awsVpc.id}
_direction="vertical"
{...props}
_style={extendStyle(props, PRIVATE_SUBNET)}
/>
);
const LoadBalancer = (props: any) => {
const { awsSubnets } = useAwsSubnets();
const { awsVpc } = useAwsVpc();
return (
<AwsLb
vpc_id={awsVpc.id}
subnets={() => awsSubnets.map((s) => s.id)}
_dependsOn={["Firewall", "Application"]}
{...props}
/>
);
};
const Firewall = (props: any) => (
<Waf
_style={{
strokeColor: "blue",
fillColor: "transparent",
}}
{...props}
/>
);
const Application = (props: any) => {
const { awsSubnet } = useAwsSubnet();
return (
<AwsInstance
subnet_id={awsSubnet.id}
ami="ami-005e54dee72cc1d00"
_dependsOn="Postgres"
{...props}
/>
);
};

The terraform code snippet is for illustration only.
output/app/app.tf.json
{
"terraform": {
"required_providers": {
"aws": {
"source": "aws",
"version": "6.22.0"
}
}
},
"provider": {
"aws": [
{
"region": "eu-west-1",
"default_tags": {
"tags": {
"iac:stack-title": "Web App",
"iac:stack-name": "web-app"
}
}
}
]
},
"data": {
"aws_vpc": {
"awsvpc_vpc": {}
}
},
"resource": {
"aws_subnet": {
"awssubnet_publicsubnet": {
"vpc_id": "${data.aws_vpc.awsvpc_vpc.id}",
"cidr_block": "10.0.0.0/16"
},
"awssubnet_privatesubnet": {
"vpc_id": "${data.aws_vpc.awsvpc_vpc.id}",
"cidr_block": "10.10.0.0/16"
}
},
"aws_lb": {
"awslb_loadbalancer": {
"vpc_id": "${data.aws_vpc.awsvpc_vpc.id}",
"subnets": [
"${aws_subnet.awssubnet_publicsubnet.id}"
]
}
},
"aws_instance": {
"awsinstance_application": {
"ami": "ami-005e54dee72cc1d00",
"subnet_id": "${aws_subnet.awssubnet_privatesubnet.id}"
}
},
"aws_db_instance": {
"awsdbinstance_postgres": {
"instance_class": "db.t3.micro"
}
}
}
}