DEV Community

Marko Milosavljevic
Marko Milosavljevic

Posted on

Terraform: Use Template file for AWS CodeDeploy AppSpec file

Terraform template files, often written in JSON or YAML, are files that are used to create dynamic content by various inputs. Using template file you can make deployments easier and more consistent.

For this example we will use AWS CodeDeploy which is a fully managed deployment service with purpose to automate deployments to different compute services such as EC2, Lambda or ECS which will be in our case. CodeDeploy ensures reliable and repeatable updates to your applications without downtime, reducing the risk of deployment failures.

The key component of AWS CodeDeploy that defines deployment actions and resource configurations is AppSpec file. When CodeDeploy is managing ECS tasks it d AppSpec file to determine ECS task definition, the container and port, along with lifecycle hooks for pre or post deployment actions. In general this file is essential part of orchestrating seamless deployments in ECS and Lambda environments.

The problem of not using template file

Without using a template file for AppSpec configuration, managing deployments becomes much more error-prone. Each time we want to make a change such as port, container name, lifecycle hooks, or anything similar we would need to manually update the AppSpec file which introduces the risk of inconsistencies, especially in environments with frequent updates. The template file automates this process and ensures that the AppSpec file is dynamically generated with the correct values for each deployment.

In this blog post, we’ll explore how to automate the creation and upload of an AppSpec file using Terraform. The goal is to dynamically generate this configuration file and store it in an S3 bucket for use with CodeDeploy.

Terraform Code Explanation

The following Terraform code achieves the dynamic creation of an AppSpec file and uploads it to an S3 bucket:

Terraform Resource: aws_s3_object

This resource uploads the dynamically generated AppSpec file to an S3 bucket:

resource "aws_s3_object" "appspec_object" {
  bucket = var.s3_bucket_id
  key    = "${var.type}/appspec.yaml"
  acl    = "private"
  content = templatefile("${path.module}/templates/appspec.yaml.tpl", {
    app_port             = var.app_port
    container_name       = "${var.type}_${var.task_definition_name}"
    task_definition_arn  = aws_ecs_task_definition.task.arn
    lambda_hook_function = aws_lambda_function.before_traffic_allow.function_name
  })
  tags = local.tags
}
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • Bucket: The AppSpec file is uploaded to a specified S3.
  • Access Control: The ACL is set to private to ensure the file isn’t publicly accessible.
  • Content: The template file function dynamically generates the AppSpec file using variables and an external template file (appspec.yaml.tpl).
  • Task definition: The ARN of the ECS Task definition is forwarded.
  • Lambda hook: The ARN of the Lambda which is triggered before traffic is switched to the new ECS Service (app version).

The AppSpec File Template: appspec.yaml.tpl

The appspec.yaml.tpl template file defines the AppSpec configuration for an ECS deployment:

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "${task_definition_arn}"
        LoadBalancerInfo:
          ContainerName: "${container_name}"
          ContainerPort: ${app_port}
Hooks:
  - BeforeAllowTraffic: "${lambda_hook_function}"
Enter fullscreen mode Exit fullscreen mode

Key points:

  • Version: Specifies the AppSpec version (0.0).
  • Resources: Defines the ECS service to be updated:
  • The TaskDefinition property refers to the ARN of the task definition.
  • LoadBalancerInfo links the container name and port for traffic routing.
  • Hooks: Includes a BeforeAllowTraffic lifecycle hook, which executes the specified Lambda function (lambda_hook_function) before traffic is routed to the updated ECS service.

Why Automate the AppSpec File?

  • Consistency: Ensures every deployment uses a correctly formatted AppSpec file with same inputs.
  • Scalability: Adapts to changes in infrastructure without manual intervention.
  • Efficiency: Reduces time spent on repetitive tasks.

Other use case examples for Template file

AWS CloudWatch Dashboard deployment can be automated repetetiby environment specific inputs ensuring consistent monitoring. For example changing region or period in input would apply to all widgets within template file.

Deployment of IAM Policies for S3 buckets can be automated via template file. For instance, you might have many buckets and many actions for different buckets. Instead of creating X policies, you could create a single template file and then make simpler calls of that file. In such a case you would have something that looks like this:

Conclusion

The AppSpec file is dynamically generated with the correct task definition ARN, container details, and Lambda hook function. The file is stored in S3, where AWS CodeDeploy can retrieve it during the deployment process. Using Terraform Template files to automate the creation of AppSpec files simplifies deployment which eliminates manual effort, ensures consistency, and increases efficiency with frequent changes.

Top comments (0)