Create your next s3 Bucket with AWS CDK and Terraform
Tags: aws, terraform, python, cdk
Published: 2022-07-30 07:27:53

What do you think of using your preferred programming language to provision your infrastructure? 

AWS CDK (Cloud Development Kit), based on CloudFormation has been released a couple of years to achieve that.

As a big fan of Terraform, I had a keen interest in the CDKTF project which aims at using AWS CDK with Terraform.

Before jumping into CDKTF, let's revisit some fundamentals concepts.

### Infrastructure as Code
Infrastructure as code (IaC) is basically, the process of managing and provisioning IT resources (in the cloud or not), through definition files or code rather than manual or interactive configuration.

The main objective is to provide a centralized way to manage configuration in terms of implementation and version control. Hereby, all changes can be validated, tested, and provisioned as part of a release process using standard deployment pipelines.

There are many benefits to using IaC for your next project: 
- Speed and safety: You expend a lot less effort on simple and repetitive tasks.
- Documentation: You can easily document your code like any software project.
- Testing: You can write tests for your project.

Now that, we know what IaC is, let's talk about Terraform which is the most popular Iac tool out there!

### Terraform
Terraform is an open-source tool created by HashiCorp in 2014. It allows you to define the infrastructure as code using a simple, declarative language called HCL (stands for Hashicorp Configuration Language) to deploy and manage that infrastructure across a variety of public cloud providers (e.g., Amazon Web Services, Microsoft Azure, Google Cloud Platform, DigitalOcean), private cloud and virtualization platforms.
If you want to deep dive into Terraform, I recommend the excellent book: [Terraform: Up & Running] (https://www.oreilly.com/library/view/terraform-up/9781492046899/) by O'Reilly.

### AWS CDK
The AWS Cloud Development Kit (AWS CDK) is an open-source framework initiated by AWS to define your cloud infrastructure in code and provision it through AWS CloudFormation.
Using the familiarity and expressive power of current programming languages, It provides high-level components called constructs that preconfigure cloud resources with proven defaults, so you can build cloud applications with ease. 

![AWS CDK Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rwlemnzh6p0nijy700j.png)
    You will find more information in the [documentation](https://docs.aws.amazon.com/cdk/index.html)

*Cloud Development Kit for Terraform (CDKTF)* is the fruit of a partnership between Hashicorp and AWS teams for leveraging the Terraform ecosystem to define and provision your infrastructure. This allows you to use Terraform without learning HashiCorp Configuration Language (HCL). 
CDKTF currently supports TypeScript, Python, Java, C#, and Go (experimental).

![AWS CDK Terraform](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpv0ciah1bb7zthgvdwr.png)
     More information from the [documentation](https://www.terraform.io/cdktf)

For this tutorial, we will use Python.

Python is one of the most easiest languages to learn and is really helpful to write scripts and automate tasks quickly. If you are new in Python, I recommend you [this platform] (https://realpython.com/) to get started.

### Prerequisites
— [python (3.10)](https://www.python.org/)
— [pipenv](https://pipenv.pypa.io/en/latest/)
— [npm](https://nodejs.org/en/)

### Installation

To use cdk with terraform, you must run the following command:

```bash
$ npm install --global cdktf-cli@latest
```

This installs the cdktf CLI that allows to spin up new projects for various languages.

We can scaffold a new python project by running:

```bash
$ mkdir s3-demo && cd s3-demo
 
$ cdktf init --template="python" --local
```

We use the option *--local* to indicate that we will use ***local state storage*** for generated Terraform. 
In a real project, it is recommended to use a [remote backend](https://www.terraform.io/language/settings/backends/configuration).

There are many files created by default.

For our demo, we will use AWS as cloud provider so we need to install the required provider.

```bash
$ pipenv install cdktf-cdktf-provider-aws
```

You can edit the `main.py` at the root of the project and add the code below:

```python
#!/usr/bin/env python
from constructs import Construct
from cdktf import App, TerraformOutput, TerraformStack
from cdktf_cdktf_provider_aws import AwsProvider, s3
# Define your stack

class MyStack(TerraformStack):
    def __init__(self, scope: Construct, ns: str):
        super().__init__(scope, ns)

        # Configure the AWS provider to use the eu-west-3 region
        AwsProvider(self, "AWS", region="eu-west-3")

        # Create your first bucket
        # pass the id of the resource and the name of the bucket
        first_bucket = s3.S3Bucket(
            self, "first_bucket",
            bucket="blog.abdelfare.me",
            acl="public-read"
        )

        TerraformOutput(self, "bucket_name", value=first_bucket.bucket)
        TerraformOutput(self, "bucket_arn", value=first_bucket.arn)

app = App()
MyStack(app, "s3-demo")

app.synth()
```

I found the SDK really intuitive.

Basically, We created our `Main Stack` inherited from the `TerraformStack` class. We set up the aws provider (Don't forget to define the AWS profile) and We create our first **S3 bucket** in one line of code.

`TerraformOutput`  allows to export some values and reuse them in another stack.

Now that, everything is ready, we can generate the terraform configuration files by running the command below:

```python
$ cdktf synth
```

We can see the new directory `cdktf.out` which contains all the terraform configuration.
This step is equivalent to the execution of the command `terraform plan.`
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tp6vmcf1j1738hthw9x4.png)
 

We can deploy our stack by running the command:
```python
$ cdktf deploy
```
This command runs `terraform apply` in the background.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opgudyp6vb1950p1koko.png)
 
We can see all the new changes and confirm the execution.

There we go!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygny8v97jdsxflmonlo4.png)
 
Our bucket was created successfully.

We can see the output of your stack by using the following command:

```python
cdktf output
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eki04vamvfe0jlol7i5o.png)
 
We can now destroy our stack by running the command:

```python
$ cdktf destroy
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3jpj1j25jzmtxakyi0ui.png)
 
## When to use CDK for Terraform

CDKTF offers many benefits, but it is not the right choice for every project. You should consider using CDKTF when:
- You have a strong preference or need to use a procedural language to define infrastructure.
- You need to create abstractions to help manage complexity. 
- You are comfortable doing your own troubleshooting and do not require commercial support.

Some pain points to consider:
- Initial CDK setup is time consuming
- Deployment times can be slow due to the synthesizing steps

Do you have any experience with CDKTF? Have you used it in production?

Feel free to share you experience with us in comment.

You could find the code of this article on [my github repo](https://github.com/abdelino17/aws-cdktf-samples-s3.git).

*In a next article, I will set up a full containerized architecture with *ECS*, *Fargate*, *ECR*, *ALB*, *CDK + Terraform* so stay tuned 😃!*