Amazon EC2 – Upgrade a1 Instances to c7g

·

By

Infracost

Amazon EC2 – Upgrade a1 Instances to c7g

·

By

Infracost

The Amazon EC2 a1 to c7g upgrade policy flags EC2 instances in the a1 family, the first AWS Graviton generation, and recommends moving them to Graviton3-based c7g. c7g does more work per vCPU, so Arm workloads can run on fewer or smaller instances and lower their compute bill. Apply this policy to any aws_instance or aws_launch_templatewhose instance_type starts with a1..

Attribute

Detail

Cloud Provider

Amazon Web Services (AWS)

Resource Type

Amazon EC2 instances in the a1 family (first-generation Graviton, Arm64)

Terraform Attribute

instance_type on aws_instance and aws_launch_template

Non-compliant Values

a1.medium, a1.large, a1.xlarge, a1.2xlarge, a1.4xlarge, a1.metal

Compliant Value

A c7g type sized to the workload, for example c7g.large

Cost Impact

About 42% higher hourly rate at the same size; savings come from running fewer or smaller c7g instances for the same work

Why This Policy Matters

How It Helps Reduce Cloud Costs

Amazon EC2 a1 instances launched in 2018 as the first EC2 instances built on AWS-designed Arm processors. AWS now treats a1 as a previous-generation family and lists c7g as its upgrade path.

AWS states that previous-generation instances remain supported. The cost case for the Amazon EC2 a1 to c7g upgrade is therefore about price-performance, not a forced migration date.

c7g instances run on Graviton3. AWS states c7g delivers up to 25% better compute performance than Graviton2-based c6g. Graviton2 itself succeeded the first-generation processor used in a1.

The a1 family also hits hard limits sooner. a1 tops out at 16 vCPUs with up to 10 Gbps of network bandwidth and up to 3,500 Mbps of EBS bandwidth. c7g scales to 64 vCPUs, with up to 30 Gbps of network bandwidth and up to 20 Gbps of EBS bandwidth on the largest sizes.

A workload on a1 that needs more throughput usually scales out by adding instances. On c7g, the same throughput often fits on fewer nodes, which is where the cost reduction shows up.

This policy is a modernization policy. It raises the hourly rate per instance at the same size, so the savings depend on right-sizing after the move.

Potential Savings

The Amazon EC2 a1 to c7g upgrade changes cost per unit of work, not cost per instance-hour. Both families use 2 GiB of memory per vCPU, so sizes map one to one.

Instance type

vCPUs

Memory

Approx. monthly on-demand cost (US East, Linux)

a1.large

2

4 GiB

$37.23

c7g.large

2

4 GiB

$52.93

a1.4xlarge

16

32 GiB

$297.84

c7g.2xlarge

8

16 GiB

$211.70

c7g.4xlarge

16

32 GiB

$423.40

Monthly figures assume 730 hours at US East (N. Virginia) on-demand Linux rates. Prices vary by region, operating system, and purchase option.

A one-for-one swap from a1.large to c7g.large raises the on-demand bill by about $15.70 per instance per month. A team that makes only that swap pays more.

Savings come from consolidation. If load testing shows a CPU-bound service fits on c7g.2xlarge instead of a1.4xlarge, each node costs about 29% less per month.

Fleet count works the same way. Replacing ten a1.xlarge instances with seven c7g.xlarge instances costs about $741 per month instead of $745, with more headroom per node.

The size of the consolidation depends on the workload. Measure it with a load test rather than assuming a fixed ratio.

Implementation Guide

Infrastructure-as-Code Example (Terraform)

The following examples show an Amazon EC2 instance on the a1 family, and the corrected configuration on c7g.

Non-compliant configuration: EC2 instance on a1

data "aws_ami" "al2_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-arm64-gp2"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2_arm64.id
  instance_type          = "a1.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}
data "aws_ami" "al2_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-arm64-gp2"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2_arm64.id
  instance_type          = "a1.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}
data "aws_ami" "al2_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-arm64-gp2"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2_arm64.id
  instance_type          = "a1.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}

This configuration runs on first-generation Graviton, with the lowest per-vCPU performance of any Graviton family. This is a common source of wasted spend on Arm workloads that were early adopters and never revisited.

Compliant configuration: EC2 instance on c7g

data "aws_ami" "al2023_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-arm64"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2023_arm64.id
  instance_type          = "c7g.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}
data "aws_ami" "al2023_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-arm64"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2023_arm64.id
  instance_type          = "c7g.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}
data "aws_ami" "al2023_arm64" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023.*-arm64"]
  }
}

resource "aws_instance" "worker" {
  ami                    = data.aws_ami.al2023_arm64.id
  instance_type          = "c7g.xlarge"
  subnet_id              = aws_subnet.private.id
  vpc_security_group_ids = [aws_security_group.worker.id]

  tags = {
    Name = "queue-worker-01"
  }
}

The core change is the instance_type value. Both families are Arm64, so an existing arm64 AMI usually keeps working. The AMI update to Amazon Linux 2023 is optional, but AWS lists Amazon Linux 2023 support as a c7g advantage over a1.

Changing only instance_type updates the instance in place. Changing ami replaces the instance, so keep the existing arm64 AMI on instances that hold local state, and roll the AMI update out separately.

The same fix applies to launch templates used by Auto Scaling groups:

resource "aws_launch_template" "workers" {
  name_prefix   = "queue-workers-"
  image_id      = data.aws_ami.al2023_arm64.id
  instance_type = "c7g.xlarge" # previously "a1.xlarge"
}
resource "aws_launch_template" "workers" {
  name_prefix   = "queue-workers-"
  image_id      = data.aws_ami.al2023_arm64.id
  instance_type = "c7g.xlarge" # previously "a1.xlarge"
}
resource "aws_launch_template" "workers" {
  name_prefix   = "queue-workers-"
  image_id      = data.aws_ami.al2023_arm64.id
  instance_type = "c7g.xlarge" # previously "a1.xlarge"
}

Step-by-Step Fix Instructions

  1. Search Terraform code for instance_type values that start with a1. in aws_instance and aws_launch_templateresources.

  2. Check shared modules, .tfvars files, and variable defaults. Instance types often sit in a variable "instance_type" default rather than in the resource block.

  3. Confirm the AMI is arm64 and that its operating system release supports Graviton3. Current Amazon Linux, Ubuntu, and Debian arm64 images do.

  4. Pick the c7g size. Start with the same vCPU count, then load test to see whether a smaller size or fewer nodes handles the same traffic.

  5. Change the instance_type value and run terraform plan. Confirm the plan shows an in-place update, not a resource replacement.

  6. Apply during a maintenance window. Changing the instance type on an aws_instance stops and starts the instance.

  7. Right-size after a week of CloudWatch CPU and network metrics. Without this step, the Amazon EC2 a1 to c7g upgrade raises cost.

  8. Add Infracost to CI/CD so new a1 instance types are flagged in pull requests before they merge.

Best Practices

  • Block new a1 types in shared modules with a validation block, so terraform plan fails before a pull request is opened.

  • Migrate development and staging instances first. Performance-sensitive code may behave differently on Graviton3.

  • Review Reserved Instances and Savings Plans before migrating. A Reserved Instance for a1 does not cover c7g usage, while Compute Savings Plans apply across instance families.

  • Do not move x86 workloads onto c7g under this policy. Moving from x86 to Arm is a separate decision with its own testing cost.

  • This policy is for workloads already on Arm64. For those teams, the Amazon EC2 a1 to c7g upgrade is the lowest-risk Graviton migration available.

A validation block for a shared module looks like this (the startswith function requires Terraform 1.3 or later):

variable "instance_type" {
  type    = string
  default = "c7g.large"

  validation {
    condition     = !startswith(var.instance_type, "a1.")
    error_message = "a1 instances are previous generation. Use a c7g type instead."
  }
}
variable "instance_type" {
  type    = string
  default = "c7g.large"

  validation {
    condition     = !startswith(var.instance_type, "a1.")
    error_message = "a1 instances are previous generation. Use a c7g type instead."
  }
}
variable "instance_type" {
  type    = string
  default = "c7g.large"

  validation {
    condition     = !startswith(var.instance_type, "a1.")
    error_message = "a1 instances are previous generation. Use a c7g type instead."
  }
}

Tools and Scripts

How does Infracost detect Amazon EC2 a1 instances automatically?

The Amazon EC2 a1 to c7g upgrade policy is available in Infracost, including in the free trial. When Infracost runs in CI/CD, it checks EC2 resources in each pull request and flags a1 instance types in the PR comment, with the file and line to change.

The same Infracost pull request comment shows the estimated monthly cost of the change. Because c7g costs more per hour at the same size, reviewers see that cost increase up front and can pick a smaller size in the same pull request.

Infracost also scans connected repositories for a1 instance types already in code. FinOps and platform teams can burn down that backlog over time, tracking issues prevented in pull requests separately from existing issues fixed.

Teams can set the policy to warn engineers or block pull requests. Teams can also limit it to new resources only, so an unrelated pull request does not force an instance change.

To find a1 instance types in a Terraform codebase:

grep -rnE '"a1\.(medium|large|xlarge|2xlarge|4xlarge|metal)"' --include="*.tf" --include="*.tfvars"
grep -rnE '"a1\.(medium|large|xlarge|2xlarge|4xlarge|metal)"' --include="*.tf" --include="*.tfvars"
grep -rnE '"a1\.(medium|large|xlarge|2xlarge|4xlarge|metal)"' --include="*.tf" --include="*.tfvars"

To list running a1 instances with the AWS CLI:

aws ec2 describe-instances \
  --filters "Name=instance-type,Values=a1.*" \
  --query "Reservations[].Instances[].{id:InstanceId,type:InstanceType,state:State.Name}" \
  --output

aws ec2 describe-instances \
  --filters "Name=instance-type,Values=a1.*" \
  --query "Reservations[].Instances[].{id:InstanceId,type:InstanceType,state:State.Name}" \
  --output

aws ec2 describe-instances \
  --filters "Name=instance-type,Values=a1.*" \
  --query "Reservations[].Instances[].{id:InstanceId,type:InstanceType,state:State.Name}" \
  --output

If an instance is managed by Terraform, change instance_type in code rather than in the console. Otherwise the next terraform apply sets the a1 type again.

Examples of Impact

Results from the Amazon EC2 a1 to c7g upgrade depend on whether the team right-sizes after the move.

Illustrative example: a queue worker fleet. A platform team runs ten a1.xlarge workers from a launch template. After moving to c7g.xlarge and load testing, the queue drains on seven nodes, giving the same monthly cost with more throughput headroom and fewer instances to patch.

Illustrative example: a single large node. A team runs an a1.4xlarge for an Arm64 build cache. After switching to c7g.2xlarge and confirming build times hold, monthly compute cost drops by about $86.

(These are illustrative scenarios, not specific customer accounts.)

Considerations and Caveats

The Amazon EC2 a1 to c7g upgrade is low risk technically, but it is not automatically cheaper.

  • Higher hourly rate. c7g costs about 42% more per hour than a1 at the same size. Without right-sizing, the bill goes up.

  • Restart required. Changing instance_type stops and starts the instance. Without an Elastic IP, the public IPv4 address changes.

  • Reservations do not move. a1 Reserved Instances do not apply to c7g. Plan the migration around reservation expiry dates.

  • Arm64 only. This policy assumes the workload already runs on Arm64. x86 binaries do not run on c7g.

  • Provider-specific. This policy targets Amazon EC2 through the aws Terraform provider. Other clouds have their own Arm-based VM families with different names.

Related Policies and Concepts

  • AWS EC2 - consider using Graviton instances: the broader policy for moving x86 EC2 workloads to Graviton, which this a1 upgrade complements for teams already on Arm.

  • Amazon EC2 - consider using latest generation instances for c family instances: the same generation-upgrade logic for x86 compute-optimized instances, where c7g is one of the targets.

  • Amazon EC2 - Consider using a preferred instance type: a related Compute-group policy that restricts EC2 instance types to an approved list, which can exclude a1 by default.

  • Amazon EC2 - consider upgrading hs1 instances to d2: another previous-generation EC2 upgrade policy built around a one-attribute instance_type change.

  • AWS ECS - consider using Graviton instances: the container equivalent for teams running ECS tasks on Graviton capacity.

Frequently Asked Questions (FAQs)

Is this policy supported in Infracost?

Yes. The Amazon EC2 a1 to c7g upgrade policy is supported in Infracost and available in the free trial. Infracost flags a1 instance types in Terraform pull requests, so the team can move to c7g before the change merges.

Can this policy be customized?

Yes. Teams can configure how Infracost enforces the Amazon EC2 a1 to c7g upgrade policy. A finding can warn engineers or block the pull request, and the policy can be limited to new resources only so existing a1 instances are not forced to change in an unrelated pull request.

Does Infracost automatically fix violations?

No. Infracost reports each Amazon EC2 a1 instance type in the pull request with the file and line to change. Picking the right c7g size requires a load test, so the team makes and applies that change.

Is this policy cloud-agnostic?

No. The Amazon EC2 a1 to c7g upgrade policy targets Amazon EC2 through the aws Terraform provider. Azure and Google Cloud offer their own Arm-based virtual machines with different resource and attribute names.

Does upgrading from a1 to c7g increase the hourly cost?

Yes, at the same size. A c7g.large costs about $0.0725 per hour in US East (N. Virginia), compared with about $0.051 for an a1.large. The Amazon EC2 a1 to c7g upgrade pays off when the faster c7g processor lets a workload run on fewer or smaller instances.

Do a1 workloads need to be recompiled for c7g?

Usually not. Amazon EC2 a1 and c7g instances both use the Arm64 architecture, so arm64 AMIs and container images that run on a1 generally run on c7g. Confirm the operating system release supports Graviton3, and test performance-sensitive code before switching production traffic.

How often should I review Amazon EC2 a1 instances?

Teams running Infracost in CI/CD get an Amazon EC2 a1 check on every pull request that touches an EC2 resource. For a1 instances already running, a quarterly review of instance generations is a reasonable cadence for most teams.

Create Free Account

This policy is supported in Infracost and available in the free trial. Sign up today and scan your code using our entire library of FinOps policies.

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies

Get started
with Infracost

© 2026 Infracost Inc

Manage cookies