diff --git a/.gitignore b/.gitignore
index 4a1f3ec..57400d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,6 @@ terraform.rc
go.mod
go.sum
+
+
+.amazonq/
\ No newline at end of file
diff --git a/README.md b/README.md
index 1e69b7c..7e49c5b 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@ Please refer to the [examples](./examples/basic) on how to get started.
| Name | Source | Version |
|------|--------|---------|
-| [ecs\_cluster](#module\_ecs\_cluster) | git::https://github.com/terraform-aws-modules/terraform-aws-ecs | 6b52c965734d95767d8e20d965afcd0db29dae5e |
+| [ecs\_cluster](#module\_ecs\_cluster) | git::https://github.com/terraform-aws-modules/terraform-aws-ecs | be968fc4af733fae2ac41dfb3c34dce7712e028f |
## Resources
@@ -86,6 +86,7 @@ Please refer to the [examples](./examples/basic) on how to get started.
| [assign\_public\_ip](#input\_assign\_public\_ip) | Whether to assign a public IP address to the ECS tasks. Set to true when using public subnets. | `bool` | `false` | no |
| [cloudwatch\_log\_group\_name](#input\_cloudwatch\_log\_group\_name) | The name of the CloudWatch log group where agent logs will be sent. | `string` | `"/hcp/hcp-terraform-agent"` | no |
| [cloudwatch\_log\_group\_retention](#input\_cloudwatch\_log\_group\_retention) | The number of days to retain logs in the CloudWatch log group. | `number` | `365` | no |
+| [cpu\_architecture](#input\_cpu\_architecture) | The CPU architecture for the ECS task. Valid values are X86\_64 and ARM64. | `string` | `"X86_64"` | no |
| [create\_cloudwatch\_log\_group](#input\_create\_cloudwatch\_log\_group) | Whether the CloudWatch log group should be created. | `bool` | `true` | no |
| [create\_ecs\_cluster](#input\_create\_ecs\_cluster) | Whether to create a new ECS cluster for the agent. | `bool` | `true` | no |
| [create\_tfe\_agent\_pool](#input\_create\_tfe\_agent\_pool) | Whether to omit agent pool/token creation | `bool` | `true` | no |
diff --git a/examples/arm64/README.md b/examples/arm64/README.md
new file mode 100644
index 0000000..8ac7636
--- /dev/null
+++ b/examples/arm64/README.md
@@ -0,0 +1,21 @@
+# ARM64 Example
+
+This example demonstrates how to deploy HCP Terraform agents on ARM64 architecture using AWS Fargate.
+
+## Key Features
+
+- Uses ARM64 CPU architecture for potentially better cost efficiency
+- Deploys on Fargate Spot instances for additional cost savings
+- Creates a new VPC with private subnets for secure agent deployment
+
+## Usage
+
+```bash
+terraform init
+terraform plan
+terraform apply
+```
+
+## Configuration
+
+The example sets `cpu_architecture = "ARM64"` to deploy agents on ARM64-based Fargate instances instead of the default x86_64 architecture.
diff --git a/examples/arm64/main.tf b/examples/arm64/main.tf
new file mode 100644
index 0000000..4cce987
--- /dev/null
+++ b/examples/arm64/main.tf
@@ -0,0 +1,59 @@
+#####################################################################################
+# Terraform module examples are meant to show an _example_ on how to use a module
+# per use-case. The code below should not be copied directly but referenced in order
+# to build your own root module that invokes this module
+#####################################################################################
+
+data "aws_availability_zones" "available" {}
+
+locals {
+ region = "us-west-2"
+ azs = slice(data.aws_availability_zones.available.names, 0, 3)
+ name = "ecs-${basename(path.cwd)}"
+ vpc_cidr = "10.0.0.0/16"
+ tags = {
+ Terraform = "true"
+ Environment = "dev"
+ ManagedBy = "aws-ia/terraform-aws-tf-cloud-agents"
+ }
+}
+
+#####################################################################################
+# MODULE INVOCATION
+#####################################################################################
+
+module "agent_pool" {
+ source = "../../"
+ name = local.name
+ hcp_terraform_org_name = var.hcp_terraform_org_name
+ agent_image = "hashicorp/tfc-agent:latest"
+ cpu_architecture = "ARM64"
+ use_spot_instances = true
+ agent_cpu = 512
+ agent_memory = 2048
+ num_agents = 1
+ vpc_id = module.vpc.vpc_id
+ subnet_ids = module.vpc.private_subnets
+ task_policy_arns = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
+ tags = local.tags
+}
+
+#####################################################################################
+# VPC
+#####################################################################################
+
+module "vpc" {
+ source = "git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=25322b6b6be69db6cca7f167d7b0e5327156a595" # v5.8.1
+
+ name = local.name
+ cidr = local.vpc_cidr
+
+ azs = local.azs
+ private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
+ public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
+
+ enable_nat_gateway = true
+ single_nat_gateway = true
+
+ tags = local.tags
+}
diff --git a/examples/arm64/outputs.tf b/examples/arm64/outputs.tf
new file mode 100644
index 0000000..1628ed3
--- /dev/null
+++ b/examples/arm64/outputs.tf
@@ -0,0 +1,49 @@
+output "agent_pool_name" {
+ description = "Name of the HCP Terraform or HCP Terraform Enterprise agent pool."
+ value = module.agent_pool.agent_pool_name
+}
+
+output "agent_pool_id" {
+ description = "ID of the HCP Terraform or HCP Terraform Enterprise agent pool."
+ value = module.agent_pool.agent_pool_id
+}
+
+output "ecs_service_arn" {
+ description = "ARN of the ECS service."
+ value = module.agent_pool.ecs_service_arn
+}
+
+output "ecs_task_arn" {
+ description = "ARN of the ECS task definition."
+ value = module.agent_pool.ecs_task_arn
+}
+
+output "ecs_task_revision" {
+ description = "Revision number of the ECS task definition."
+ value = module.agent_pool.ecs_task_revision
+}
+
+output "log_stream_prefix" {
+ description = "Prefix for the CloudWatch log stream."
+ value = module.agent_pool.log_stream_prefix
+}
+
+output "security_group_name" {
+ description = "Name of the VPC security group attached to the service."
+ value = module.agent_pool.security_group_name
+}
+
+output "security_group_id" {
+ description = "ID of the VPC security group attached to the service."
+ value = module.agent_pool.security_group_id
+}
+
+output "task_role_name" {
+ description = "Name of the IAM role attached to the task containers."
+ value = module.agent_pool.task_role_name
+}
+
+output "task_role_arn" {
+ description = "ARN of the IAM role attached to the task containers."
+ value = module.agent_pool.task_role_arn
+}
diff --git a/examples/arm64/providers.tf b/examples/arm64/providers.tf
new file mode 100644
index 0000000..538f05e
--- /dev/null
+++ b/examples/arm64/providers.tf
@@ -0,0 +1,19 @@
+terraform {
+ required_version = ">= 1.5.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 5.47.0"
+ }
+ }
+}
+
+
+provider "aws" {
+ region = local.region
+}
+
+provider "tfe" {
+ token = var.tfe_token
+}
\ No newline at end of file
diff --git a/examples/arm64/variables.tf b/examples/arm64/variables.tf
new file mode 100644
index 0000000..d2c7306
--- /dev/null
+++ b/examples/arm64/variables.tf
@@ -0,0 +1,9 @@
+variable "hcp_terraform_org_name" {
+ type = string
+ description = "The name of the HCP Terraform organization."
+}
+
+variable "tfe_token" {
+ type = string
+ description = "Terraform token to be used to create the agent pool."
+}
\ No newline at end of file
diff --git a/main.tf b/main.tf
index cc16ec2..7e8b549 100644
--- a/main.tf
+++ b/main.tf
@@ -44,7 +44,7 @@ data "aws_iam_policy_document" "kms_key_policy" {
"kms:*",
]
resources = [
- "arn:aws:kms:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:key/*"
+ "arn:aws:kms:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:key/*"
]
}
statement {
@@ -53,7 +53,7 @@ data "aws_iam_policy_document" "kms_key_policy" {
principals {
type = "Service"
identifiers = [
- "logs.${data.aws_region.current.name}.amazonaws.com",
+ "logs.${data.aws_region.current.id}.amazonaws.com",
"ssm.amazonaws.com"
]
}
@@ -65,7 +65,7 @@ data "aws_iam_policy_document" "kms_key_policy" {
"kms:Describe*"
]
resources = [
- "arn:aws:kms:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:key/*"
+ "arn:aws:kms:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:key/*"
]
}
}
@@ -94,6 +94,7 @@ resource "aws_ecs_task_definition" "hcp_terraform_agent" {
runtime_platform {
operating_system_family = "LINUX"
+ cpu_architecture = var.cpu_architecture
}
container_definitions = jsonencode(
@@ -107,7 +108,7 @@ resource "aws_ecs_task_definition" "hcp_terraform_agent" {
options : {
awslogs-create-group : "true",
awslogs-group : var.create_cloudwatch_log_group ? aws_cloudwatch_log_group.cloudwatch[0].name : var.cloudwatch_log_group_name
- awslogs-region : data.aws_region.current.name
+ awslogs-region : data.aws_region.current.id
awslogs-stream-prefix : "hcp-tf-${var.hcp_terraform_org_name}-${var.name}"
}
}
@@ -209,20 +210,16 @@ resource "aws_security_group_rule" "allow_egress" {
module "ecs_cluster" {
count = var.create_ecs_cluster ? 1 : 0
- source = "git::https://github.com/terraform-aws-modules/terraform-aws-ecs?ref=6b52c965734d95767d8e20d965afcd0db29dae5e" # v5.11.2
+ source = "git::https://github.com/terraform-aws-modules/terraform-aws-ecs?ref=be968fc4af733fae2ac41dfb3c34dce7712e028f" # v6.6.1
cluster_name = var.name
- fargate_capacity_providers = {
+ default_capacity_provider_strategy = {
FARGATE = {
- default_capacity_provider_strategy = {
- weight = 50
- }
+ weight = var.use_spot_instances ? 0 : 100
}
FARGATE_SPOT = {
- default_capacity_provider_strategy = {
- weight = 50
- }
+ weight = var.use_spot_instances ? 100 : 0
}
}
diff --git a/variables.tf b/variables.tf
index bfe53d4..a6ae798 100644
--- a/variables.tf
+++ b/variables.tf
@@ -85,6 +85,16 @@ variable "agent_image" {
default = "hashicorp/tfc-agent:latest"
}
+variable "cpu_architecture" {
+ type = string
+ description = "The CPU architecture for the ECS task. Valid values are X86_64 and ARM64."
+ default = "X86_64"
+ validation {
+ condition = contains(["X86_64", "ARM64"], var.cpu_architecture)
+ error_message = "Valid values: X86_64, ARM64"
+ }
+}
+
variable "agent_single_execution" {
type = bool
description = "Whether to use single-execution mode."