Skip to content

Elastic Compute Cloud (EC2)

A virtual machine in the cloud. You choose the operating system image and the instance size, and your team patches and maintains everything that runs on it. At BYM, teams use EC2 for third-party software that needs a server of its own, such as Windows-based GIS tools or license servers.

Consider ECS Fargate or Lambda first

ECS Fargate and Lambda cover most use cases with less operational overhead. AWS manages the servers for both, so you don't patch an operating system or plan disk space. See ECS Fargate and Lambda Function.

Terraform configuration

terraform-byks-module doesn't create EC2 instances. Provision each instance directly with the terraform-aws-ec2-instance module, outside the module "application" block. Each module block creates one instance with an encrypted root volume, optional extra EBS volumes, an optional Elastic IP, and a Route53 DNS record. The instance always requires IMDSv2 tokens for its metadata service.

The module doesn't create a security group, a key pair, or an IAM instance profile. Create the ones you need yourself and pass them in, as the example does with the security group.

The module creates DNS records through the aws.route53 provider, which your Terraform Infrastruktur-repo defines in route53_provider.tf. Pass it in through providers, as in the example. See Terraform Infrastruktur-repos.

ec2.tf
data "aws_ssm_parameter" "vpc_information" {
  name = "/bym/vpc"
}

data "aws_route53_zone" "route53_zone" {
  provider = aws.route53
  name     = "test.bymoslo.net"
}

locals {
  vpc = jsondecode(data.aws_ssm_parameter.vpc_information.insecure_value)
}

resource "aws_security_group" "example" {
  name   = "example-ec2"
  vpc_id = local.vpc.vpc_id
}

module "ec2" {
  source = "git@github.com:BYM-IKT/terraform-aws-ec2-instance.git?ref=v2"
  application_name             = "example"
  environment                  = var.environment
  instance_name                = "example"
  ami                          = "ami-0123456789abcdef0"
  instance_type                = "t3.small"
  subnet_ids                   = local.vpc.private_subnets
  aws_security_group_public_id = [aws_security_group.example.id]
  key_name                     = "example"
  associate_public_ip_address  = false
  disable_api_termination      = true
  zone_id                      = data.aws_route53_zone.route53_zone.zone_id
  instance_route53             = "example-int.test.bymoslo.net"
  eip_assoc                    = false

  providers = {
    aws.route53 = aws.route53
  }
  # options go here
}

Options

Option Type Default Description
application_name any required Name of the application using the instance. Part of the KMS key alias names, together with environment, so it must be unique for each instance in the account.
environment any required Environment the instance belongs to, for example test or prod. Part of the KMS key alias names.
instance_name any required Name of the instance. Sets the Name tag on the instance, its volumes, and its Elastic IP.
ami any required ID of the Amazon Machine Image (AMI) to launch, which sets the operating system. AMI IDs differ between regions. Changing it replaces the instance.
instance_type any required Instance size, which sets CPU and memory, for example t3.small.
subnet_ids list(string) required Subnets to launch the instance in. Only the first subnet in the list is used. Use private_subnets from the /bym/vpc SSM parameter, as in the example, unless the instance needs a public IP address.
aws_security_group_public_id list(string) required IDs of the security groups to attach to the instance. Despite the name, the groups don't need to allow public traffic. Add an RDS access security group here to let the instance reach the database.
key_name any required Name of an existing EC2 key pair for logging in over SSH or RDP.
associate_public_ip_address any required Give the instance a public IP address. Needs a public subnet in subnet_ids. Also decides whether the DNS record points to the public or the private IP address.
disable_api_termination any required Block termination of the instance. Set to false before you delete the instance on purpose.
zone_id any required ID of the Route53 hosted zone for the DNS records, for example test.bymoslo.net in test and bymoslo.no in prod. Required even when r53_ipv4 and r53_ipv6 are both false.
instance_route53 string "" DNS name for the instance, for example example-int.test.bymoslo.net. Required when r53_ipv4 is true.
r53_ipv4 bool true Create an A record for instance_route53 in zone_id.
r53_ipv6 bool false Create an AAAA record for instance_route53. The module points it at the instance's IPv4 address, which Route53 rejects, so leave it false.
availability_zone string "" Availability zone for the extra EBS volumes, for example eu-west-1b. Required when ebs_volume_count is above 0, and must match the zone of the first subnet in subnet_ids. The instance itself always launches in that subnet's zone.
root_volume_type string "gp2" Root volume type. Either standard, gp2, gp3, io1, or io2.
root_volume_size number 10 Size of the root volume in GB.
root_iops number 0 Provisioned IOPS for the root volume. Only applies to gp3, io1, and io2, and required for io1 and io2.
root_throughput number 0 Throughput of the root volume in MiB/s. Only applies to gp3.
ebs_device_name list(string) /dev/xvdb to /dev/xvdz Device names for the extra EBS volumes, used in order.
ebs_volume_type string "gp2" EBS volume type for the extra volumes. Either standard, gp2, gp3, io1, or io2.
ebs_volume_size number 10 Size of each extra EBS volume in GB.
ebs_volume_encrypted bool true Encrypt the extra EBS volumes with a KMS key the module creates.
ebs_iops number 0 Provisioned IOPS for each extra EBS volume. Only applies to gp3, io1, and io2, and required for io1 and io2.
ebs_throughput number 0 Throughput of each extra EBS volume in MiB/s. Only applies to gp3.
ebs_volume_count number 0 Number of extra EBS volumes to attach. They all share the same type, size, and encryption settings.
delete_on_termination bool true Delete the root volume when the instance is terminated. Doesn't apply to the extra EBS volumes.
ebs_optimized bool false Launch the instance as EBS-optimized, with dedicated bandwidth to its volumes.
instance_profile string "" Name of an existing IAM instance profile to attach. The module doesn't create one, so with "" the instance has no IAM role and can't call AWS APIs, for example Systems Manager.
monitoring bool true Turn on detailed CloudWatch monitoring, which reports metrics every minute instead of every five minutes.
root_block_device_encrypted bool true Encrypt the root volume with a KMS key the module creates.
eip_assoc bool true Create an Elastic IP and attach it to the instance, giving it a fixed public IP address. Set to false for an instance that shouldn't be reachable from the internet.
instance_tags map(string) {} Extra tags applied to the instance, for example PatchGroup for Systems Manager patching.
backup_settings any {} AWS Backup schedule and retention settings for the instance. See Backup settings object.

Backup settings object

Used in backup_settings.

Option Type Default Description
hourly bool false Take hourly backups.
hourly_retention_days number 7 Days to keep hourly backups. Must be 2 or 7.
twelve_hours bool false Take backups every twelve hours.
twelve_hours_retention_days number 14 Days to keep twelve-hour backups. Must be 14.
daily bool false Take daily backups.
daily_retention_days number 14 Days to keep daily backups. Must be 5, 10, 14, or 35.
biweekly bool false Take backups every two weeks.
biweekly_retention_days number 185 Days to keep biweekly backups. Must be 185.
monthly bool false Take monthly backups.
monthly_retention_days number 370 Days to keep monthly backups. Must be 95, 185, 370, or 1850.
monthly_annually bool false Take an extra yearly backup alongside the monthly one.
monthly_retention_years number 5 Years to keep the yearly backup. Must be 5.
biannual bool false Take backups every six months.
biannual_retention_days number 370 Days to keep biannual backups. Must be 370.
daily_no_copy bool false Take daily backups on the no-copy plan, instead of daily.
daily_no_copy_retention_days number 14 Days to keep no-copy daily backups. Must be 1, 14, or 35.
biweekly_no_copy bool false Take biweekly backups on the no-copy plan, instead of biweekly.
biweekly_no_copy_retention_days number 35 Days to keep no-copy biweekly backups. Must be 35.
monthly_no_copy bool false Take monthly backups on the no-copy plan, instead of monthly.
monthly_no_copy_retention_days number 370 Days to keep no-copy monthly backups. Must be 370.
biannual_no_copy bool false Take biannual backups on the no-copy plan, instead of biannual.
biannual_no_copy_retention_days number 740 Days to keep no-copy biannual backups. Must be 740.

Outputs

Read these from the module, for example module.ec2.private_ip.

Output Description
id ID of the instance.
arn ARN of the instance.
private_ip Private IP address of the instance.
public_ip Public IP address of the instance, if it has one.
ebs_ids IDs of the extra EBS volumes.

Resources