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.
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
-
AWS documentation
Official AWS documentation for EC2