Easily Customize Nitric's Terraform Providers

2 min read

Nitric's Terraform Providers are designed to be flexible and customizable, serving as a reference implementation that you can easily override to fit your specific needs.

This brief guide demonstrates the ease of customizing the Nitric framework. If you’re new to Nitric and the concepts of Infrastructure from Code (IfC), we recommend starting with our quickstart documentation, which utilizes Pulumi providers written in Go.

Let’s take a look at how you can customize the configuration of an AWS S3 bucket to enable server-side encryption.

Default S3 Bucket Configuration

By default, the S3 bucket module in Nitric’s Terraform Providers is configured as follows:

# Generate a random id for the bucket
resource "random_id" "bucket_id" {
  byte_length = 8

  keepers = {
    # Generate a new id each time we switch to a new AMI id
    bucket_name = var.bucket_name
  }
}

# AWS S3 bucket
resource "aws_s3_bucket" "bucket" {
  bucket = "${var.bucket_name}-${random_id.bucket_id.hex}"

  tags = {
    "x-nitric-${var.stack_id}-name" = var.bucket_name
    "x-nitric-${var.stack_id}-type" = "bucket"
  }
}

# Deploy bucket lambda invocation permissions
resource "aws_lambda_permission" "allow_bucket" {
  for_each = var.notification_targets
  action        = "lambda:InvokeFunction"
  function_name = each.value.arn
  principal     = "s3.amazonaws.com"
  source_arn    = aws_s3_bucket.bucket.arn
}

# Deploy lambda notifications
resource "aws_s3_bucket_notification" "bucket_notification" {
  bucket = aws_s3_bucket.bucket.id

  dynamic "lambda_function" {
    for_each = var.notification_targets
    content {
      lambda_function_arn = lambda_function.value.arn
      events              = lambda_function.value.events
      filter_prefix       = lambda_function.value.prefix
    }
  }
}

Adding Server-Side Encryption

To customize this configuration and add server-side encryption to the S3 bucket, you can extend the module by adding the following snippet to your S3 module.

# AWS S3 bucket server-side encryption configuration
resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_encryption" {
  bucket = aws_s3_bucket.bucket.bucket

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

Applying the Customization

Nitric already has build scripts that allow you to rebuild the Terraform provider and use it immediately.

You can run make install from the provider's root directory here once you've customized your resources. The make file will install your provider as nitric/awstf@0.0.1 by default, which can be used directly in your stack file.

# The nitric provider to use
provider: nitric/awstf@0.0.1

# The target aws region to deploy to
region: us-east-2

After running nitric up you can inspect your bucket's configuration on the AWS console.

aws-console

Why We Didn’t Start with Encryption by Default?

The default configurations aim to be as simple as possible to cater to a wide range of use cases and to serve as a starting point for users.

While basic server-side encryption using AWS-managed keys (SSE-S3) does not require additional permissions, using more advanced encryption options like SSE-KMS (AWS Key Management Service) involves managing dependencies on KMS and configuring the necessary permissions and roles.

Conclusion

This example demonstrates how easy it is to customize Nitric's Terraform Providers to meet your specific requirements. By leveraging Terraform's modular and extensible nature, you can tailor infrastructure configurations to suit your needs while maintaining the flexibility and power of Nitric’s framework.

Watch this demonstration of the Terraform providers to learn more about how they work and how Nitric fits into your ecosystem.

Previous Post
Maximizing Terraform Modules for Platform Engineering
Next Post
Nitric’s Terraform Providers: Transform Your Terraform Workflows