Skip to content

Commit

Permalink
Merge pull request #1112 from hashicorp/doc-architecture-972
Browse files Browse the repository at this point in the history
chore(docs): CDK for Terraform Architecture
  • Loading branch information
skorfmann authored Oct 15, 2021
2 parents 2ee8a18 + 80da36e commit 4b5e97d
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 53 deletions.
2 changes: 1 addition & 1 deletion website/docs/cdktf/cli-reference/commands.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ $ cdktf login

## synth

This command synthesizes Terraform configuration for an application.
This command synthesizes Terraform configuration for an application. CDKTF stores the synthesized configuration in the `cdktf.out` directory, unless you use the `--output` flag to specify a different location. The output folder is ephemeral and might be erased for each `synth` that you run manually or that happens automatically when you run `deploy`, `diff`, or `destroy`.

```sh
$ cdktf synth --help
Expand Down
66 changes: 61 additions & 5 deletions website/docs/cdktf/concepts/cdktf-architecture.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,71 @@
layout: "cdktf"
page_title: "CDKTF Architecture"
sidebar_current: "cdktf"
description: "Learn the key components of CDK for Terraform applications and how they communicate with Terraform."
description: "Key CDK for Terraform components and application structure."
---

# Architecture

**Existing content - use if helpful, delete if not helpful**
This page explains the tools and processes that CDK for Terraform (CDKTF) uses to leverage the Terraform ecosystem and convert code into Terraform configuration files. It also explains the major components of a CDKTF application and how those pieces fit together.

When you use CDKTF, you create an **application** that uses CDKTF libraries to convert infrastructure definitions into JSON configuration files for Terraform. An application can have one or more **stacks**, which represent a collection of infrastructure that will be synthesized as a dedicated Terraform configuration. This allows you to separate the state management for multiple environments with the same infrastructure, like test and production.
## CDKTF Building Blocks

## Applications
CDKTF leverages existing libraries and tools to help convert the definitions you write in your preferred programming language to Terraform configuration files. It also uses Terraform to provision and manage your infrastructure when you deploy your application.

CDK for Terraform apps are structured as a tree of [constructs](https://github.com/aws/constructs). The classes `App`, `TerraformStack`, `TerraformResource` and `Resource` are all deriving from `Construct` and are therefore represented as a node in the application tree, where the `App` node is the root.
### Amazon Web Services Cloud Development Kit

CDKTF shares core concepts and components with the [Amazon Web Services Cloud Development Kit](https://aws.amazon.com/cdk/) (AWS CDK), a tool that allows you to use familiar programming languages to define infrastructure on AWS CloudFormation. AWS CDK and CDK for Terraform are different products, and you cannot yet use [AWS CDK constructs](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html) within CDKTF. We are actively working on an [interoperability layer](https://github.com/hashicorp/terraform-cdk/pulls?q=is%3Apr+is%3Aopen+label%3Afeature%2Faws-adapter) to enable this in future releases.

### jsii

The [`jsii` tool](https://aws.github.io/jsii/) enables publishing polyglot libraries in all supported languages from a single Typescript code base. CDKTF uses Typescript types to generate an assembly file that `jsii` uses to generate the code bindings for the other supported languages.

### Terraform

CDKTF [synthesizes](/cdktf/cli-reference/commands.html#synth) infrastructure defined in a supported programming language into [JSON configuration files](https://www.terraform.io/docs/language/syntax/json.html) that Terraform can use to manage infrastructure.

The diagram below shows how synthesizing a CDKTF application produces a series of artifacts in a designated output folder. You can then either use the JSON file with Terraform directly or provision your infrastructure using CDKTF CLI commands. All CDKTF CLI operations like `diff`, `deploy`, and `destroy` communicate with Terraform for execution.

![cdktf-terraform](./images/cdktf-terraform-workflow.png)

CDKTF also automatically extracts the schemas from existing Terraform [providers](./providers.html) or [modules](./modules.html) and generates the necessary code bindings for your application.

![cdktf-terraform](./images/provider-modules.png)

## CDKTF Components

CDKTF has two major components that allow you to define and provision infrastructure.

- **Lib:** This is the `cdktf` package that is the foundation for each CDKTF project. It contains all of the core libraries that allow you to leverage the Terraform ecosystem and synthesize your application into Terraform configuration files.

- **CLI:** The [`cdktf` CLI](/cdktf/cli-reference/cli-configuration.html) allows you to initialize a new CDKTF project, adjust project settings, synthesize your infrastructure into Terraform configuration files, deploy your CDKTF application, and more. Refer to the [CLI commands documentation](/cdktf/cli-reference/commands.html) for more details. You can also use some Terraform CLI commands like `terraform apply` and `terraform destroy` directly, but we recommend using the available `cdktf cli` commands where possible.

## Application Architecture

CDKTF applications are structured as a tree of [constructs](https://github.com/aws/constructs), which the AWS documentation defines as "classes that define a 'piece of system state'". The foundational classes to build a CDKTF application are `App`, `Stack`, and `Resource`.

![cdktf-terraform](./images/cdktf-app-architecture.png)

### `App` Class

Each CDKTF project has one or more `App` instances that act as a container for the infrastructure configurations you create and deploy. An `App` can have one or more [`Stacks`](./stacks.html) that represent a collection of related infrastructure.

### `Stack` Class

A `Stack` represents a collection of infrastructure resources that CDKTF synthesizes as a separate Terraform configuration. It is equivalent to a [Terraform working directory](https://www.terraform.io/docs/cli/init/index.html).

Stacks allow you to separate the state management within an application. For example, you may want to deploy and manage separate infrastructure resources for development and testing. Reference the [stack documentation](./stacks.html) for more details on when and how to use stacks in your project.

### `Resource` Class

A `Resource` represents the definition for one or more infrastructure objects. Resources and their required attributes vary depending on the provider. Reference the [providers and resources documentation](./providers-and-resources.html#resources) for more details.

### Constructs

Rather than defining resources by hand, you can leverage constructs to reuse existing resource configurations written in your programming language. For example, you might create a construct that describes a Kubernetes deployment, import it into your application, and customize the deployment via the exposed properties.

Here is an example of a [custom construct written in TypeScript](https://github.com/skorfmann/cdktf-hybrid-module/blob/7a84cbea62fbc3c3b7e92c00d75fcaad495cf29b/packages/cdktf-hybrid-module/lib/construct.ts) that creates a machine image. The exported interface allows users to specify the instance type and one or more tags. The rest of the configuration is defined in the construct and is abstracted from the consumer.

### Examples

Reference the [examples page](/docs/cdktf/examples.html) to see configured CDKTF applications in each supported programming language.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 15 additions & 38 deletions website/docs/cdktf/concepts/stacks.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,13 @@
layout: "cdktf"
page_title: "Stacks"
sidebar_current: "cdktf"
description: "TBD"
description: "Use stacks to specify separate collections of infrastructure for different environments, like test and production."
---

# Stacks

A stack represents a collection of infrastructure that will be synthesized as a dedicated Terraform configuration. Stacks allow you to separate the state management for multiple environments within an application.

## Global Configuration

The app is host of stacks and the root node in the constructs tree. It can be used to provide global configuration to each stack and underlying constructs.

One option to provide global configuration is the app `context`, which can be accessed in any construct within the app.

```typescript
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, Instance } from "./.gen/providers/aws";

class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);

new AwsProvider(this, "aws", {
region: "us-east-1",
});

new Instance(this, "Hello", {
ami: "ami-2757f631",
instanceType: "t2.micro",
tags: {
myConfig: this.node.getContext("myConfig"),
},
});
}
}

const app = new App({ context: { myConfig: "config" } });
new MyStack(app, "hello-cdktf");
app.synth();
```

### Single Stack

The following example will synthesize a single Terraform configuration in the configured output folder. When you run `cdktf synth`, the synthesized Terraform configuration will be in the folder `cdktf.out/stacks/a-single-stack`
Expand Down Expand Up @@ -148,12 +114,11 @@ Please track this [issue](https://github.com/hashicorp/terraform-cdk/issues/651)

##### Migration from `<= 0.2`

Up until CDK for Terraform version `0.2` only a single stack was supported. For local state handling, a `terraform.tfstate` in the project root folder was used. With version `>= 0.3` the local state file reflects the stack name it belongs to in its file name. When a `terraform.tfstate` file is still present in the project root folder, it has to be renamed to match the schema `terraform.<stack-name>.tfstate` manually.
Up until CDK for Terraform version `0.2` only a single stack was supported. For local state handling, a `terraform.tfstate` in the project root folder was used. With version `>= 0.3`, the local state file reflects the stack name it belongs to in its file name. When a `terraform.tfstate` file is still present in the project root folder, it has to be renamed to match the schema `terraform.<stack-name>.tfstate` manually.

#### Escape Hatch

For anything on the top-level `terraform` block that is not natively implemented, use the **stack escape hatch** to define a configuration. For example,
define remote backend using the `addOverride` method in TypeScript.
For anything on the top-level `terraform` block that is not natively implemented, use the **stack escape hatch** to define a configuration. For example, define remote backend using the `addOverride` method in TypeScript.

~> **Important**: Escape hatches **must not** have empty arguments or objects, as they will be removed from the synthesized JSON configuration.

Expand Down Expand Up @@ -187,3 +152,15 @@ This will synthesize a Terraform configuration with the remote backend included
}
}
```

### Current Limitations

#### Deployments

All Terraform operations are currently limited to a single stack, so you must specify a target stack directory to run `diff`, `deploy` or `destroy`. CDKTF emits an error if you omit the target stack and run a plain `cdktf deploy`. In the future, we plan to add support for deploying all or a subset of stacks. Please track this [issue](https://github.com/hashicorp/terraform-cdk/issues/650) if you're interested in this feature.

To run multiple stacks at once, move them into the same directory and run `cdktf deploy`. For example, you could create a combined directory called `multiple-stacks-dev`, run `cdktf deploy multiple-stacks-dev`, and all Terraform operations will run in the folder `cdktf.out/stacks/multiple-stacks-dev`.

#### Cross Stack References

Referencing resources from another stack is not yet supported automatically. You can achieve this with [Outputs](website/docs/cdktf/concepts/variables-and-outputs.html.md) and the [Remote State data source](https://www.terraform.io/docs/language/state/remote-state-data.html). Please track this [issue](https://github.com/hashicorp/terraform-cdk/issues/651) if you're interested in cross-stack references.
58 changes: 56 additions & 2 deletions website/docs/cdktf/create-and-deploy/project-setup.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,61 @@ cdktf deploy --auto-approve

## Project Configuration

Installing CDK for Terraform with a pre-built template generates a basic `cdktf.json` file in your root directory that you can customize for your application. This config file is where you can define the [providers](/docs/cdktf/concepts/providers-and-resources.html) and [modules](docs/cdktf/concepts/modules.html) that should be added to the project, and also supply custom configuration settings for the application. Refer to the [cdktf.json documentation](/docs/cdktf/create-and-deploy/configuration-file.html) for more detail.
Initializing your project with a template generates a basic project in your preferred programming language that you can customize for your use case. You can manage global configuration for your project by customizing the `cdktf.json` configuration file or the application context.

### `cdktf.json` Configuration File

Installing CDK for Terraform with a pre-built template generates a basic `cdktf.json` file in your root directory that you can customize for your application. This config file is where you can define the [providers](/docs/cdktf/concepts/fundamentals/providers.html) and [modules](docs/cdktf/concepts/fundamentals/modules.html) that should be added to the project, and also supply custom configuration settings for the application. Refer to the [cdktf.json documentation](/docs/cdktf/create-and-deploy/configuration-file.html) for more detail.

### Application Context

All of the classes in your application can access the application `context`, so it is an ideal place to store project configuration. Context becomes available to any construct in your application after you run `cdktf synth`.

You can configure context as a static value in `cdktf.json` by setting the `context` property.

```jsonc
{
// ...
"context": {
"myConfig": "value"
}
```
You can also provide context when instantiating the `App` class.
```ts
const app = new App({ context: { myConfig: "value" } });
```
The TypeScript example below uses `App` context to provide a custom tag value to an AWS EC2 instance.
```typescript
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, Instance } from "./.gen/providers/aws";

class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);

new AwsProvider(this, "aws", {
region: "us-east-1",
});

new Instance(this, "Hello", {
ami: "ami-2757f631",
instanceType: "t2.micro",
tags: {
myConfig: this.node.getContext("myConfig"),
},
});
}
}

const app = new App({ context: { myConfig: "value" } });
new MyStack(app, "hello-cdktf");
app.synth();
```
## Convert Existing HCL project
Expand Down Expand Up @@ -143,4 +197,4 @@ new MyStack(app, "cdktf-demo");
app.synth();
```
The ability to initialize a new CDKTF project from an HCL project is currently limited to projects that use the `typescript` template, but you can use the `cdktf convert` command to convert individual HCL files to another programming language. Refer to the [`cdktf convert` command documentation](/docs/cdktf/cli-reference/commands.html) for more information.
Initializing a new CDKTF project from an HCL project is currently limited to projects that use the `typescript` template, but you can use the `cdktf convert` command to convert individual HCL files to another programming language. Refer to the [`cdktf convert` command documentation](/docs/cdktf/cli-reference/commands.html) for more information.
14 changes: 7 additions & 7 deletions website/docs/cdktf/examples.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ Each CDK for Terraform project can specify a [backend](https://www.terraform.io/

### Java

| Example | Description |
| --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [aws](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/aws) | Provisions a DynamoDB table on the AWS provider. |
| [azure](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/azure) | Provisions a Virtual Network on Microsoft Azure. |
| [google](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/google) | Creates a simple Compute Instance with the Google Cloud Platform Provider. |
| Example | Description |
| --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [aws](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/aws) | Provisions a DynamoDB table on the AWS provider. |
| [azure](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/azure) | Provisions a Virtual Network on Microsoft Azure. |
| [google](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/google) | Creates a simple Compute Instance with the Google Cloud Platform Provider. |
| [gradle-shared-module](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/gradle-shared-module) | Uses gradle to build and share two AWS modules. [Modules](/docs/cdktf/concepts/modules.html) are distinct configurations that you can package and reuse across projects and teams. |
| [kubernetes](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/kubernetes) | Schedules and exposes a NGINX deployment on a Kubernetes cluster. |
| [ucloud](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/ucloud) | Provisions a Linux base image on UCloud. |
| [kubernetes](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/kubernetes) | Schedules and exposes a NGINX deployment on a Kubernetes cluster. |
| [ucloud](https://github.com/hashicorp/terraform-cdk/tree/main/examples/java/ucloud) | Provisions a Linux base image on UCloud. |

### C Sharp

Expand Down
Loading

0 comments on commit 4b5e97d

Please sign in to comment.