Awesome
Modernisation Platform Terraform EC2 Instance
Usage
module "ec2_test_instance" {
source = "github.com/ministryofjustice/modernisation-platform-terraform-ec2-instance"
providers = {
aws.core-vpc = aws.core-vpc # core-vpc-(environment) holds the networking for all accounts
}
for_each = try(local.ec2_test.ec2_test_instances, {})
name = each.key
ami_name = each.value.ami_name
ami_owner = try(each.value.ami_owner, "core-shared-services-production")
instance = merge(local.ec2_test.instance, lookup(each.value, "instance", {}))
ebs_volumes_copy_all_from_ami = try(each.value.ebs_volumes_copy_all_from_ami, true)
ebs_kms_key_id = module.environment.kms_keys["ebs"].arn
ebs_volume_config = lookup(each.value, "ebs_volume_config", {})
ebs_volumes = lookup(each.value, "ebs_volumes", {})
ebs_volume_tags = lookup(each.value, "ebs_volume_tags", {})
ssm_parameters_prefix = lookup(each.value, "ssm_parameters_prefix", "test/")
ssm_parameters = lookup(each.value, "ssm_parameters", null)
route53_records = merge(local.ec2_test.route53_records, lookup(each.value, "route53_records", {}))
iam_resource_names_prefix = "ec2-test-instance"
instance_profile_policies = local.ec2_common_managed_policies
business_unit = local.business_unit
application_name = local.application_name
environment = local.environment
region = local.region
availability_zone = local.availability_zone_1
subnet_id = module.environment.subnet["private"][local.availability_zone_1].id
tags = merge(local.tags, local.ec2_test.tags, try(each.value.tags, {}))
account_ids_lookup = local.environment_management.account_ids
cloudwatch_metric_alarms = {}
}
For a deployed example, please check example. A second fully self-contained example has been added for ease of use.
Setting backup tags
Read the Modernisation Platform backup functionality to understand how the backup plan works. The following is a summary of the backup behaviour based on the tags that are set and passed in this module.
Production environment
By default, all production resources (EC2 and EBS) will be backed up. This is determined by the is-production
tag being set to true
.
Production backups can be skipped by setting backup
tag to false
(passed in tags
input).
Non-production environments
Additionally, you are able to control backups in non-production environments by setting backup
tag to true
(passed in tags
input).
Backup duplication problem
NOTE, setting backup
tag to true
that is passed in tags
input will set backup
tag to true
on all EC2 and EBS resources.
This will result in duplicated backups as EBS resources that are part of an EC2 will get backed up during the EC2 backup and EBS backup selection by the backup plan.
In order to select either EC2 backups or EBS backups it is possible to set backup
tag to true
on only EC2 instance, by passing the tag as part of the instance.tags
input or setting the backup
tag to true
on only EBS by setting the backup
tag to true
and passing it in the ebs_volume_tags
input.
NOTE, if the backup
tag is passed in tags
and instance.tags
/ebs_volume_tags
, the tag set on the specific resources will take priority.
For example, backup
tag is set to:
true
viatags
inputfalse
viainstance.tags
inputtrue
viaebs_volume_tags
input will result in:- EC2 not being backed up
- all EBS being backed up (that includes root ebs, inline ebs and attached ebs).
Looking for issues?
If you're looking to raise an issue with this module, please create a new issue in the Modernisation Platform repository.
<!-- BEGIN_TF_DOCS -->Requirements
Name | Version |
---|---|
<a name="requirement_terraform"></a> terraform | >= 1.1.7 |
<a name="requirement_aws"></a> aws | ~> 5.0 |
<a name="requirement_cloudinit"></a> cloudinit | ~> 2.3.5 |
<a name="requirement_random"></a> random | ~> 3.0 |
<a name="requirement_time"></a> time | > 0.9.0 |
Providers
Name | Version |
---|---|
<a name="provider_aws"></a> aws | ~> 5.0 |
<a name="provider_aws.core-vpc"></a> aws.core-vpc | ~> 5.0 |
<a name="provider_cloudinit"></a> cloudinit | ~> 2.3.5 |
<a name="provider_random"></a> random | ~> 3.0 |
Modules
No modules.
Resources
Name | Type |
---|---|
aws_cloudwatch_metric_alarm.this | resource |
aws_ebs_volume.this | resource |
aws_eip.this | resource |
aws_eip_association.this | resource |
aws_iam_instance_profile.this | resource |
aws_iam_role.this | resource |
aws_iam_role_policy.ssm_params_and_secrets | resource |
aws_instance.this | resource |
aws_route53_record.external | resource |
aws_route53_record.internal | resource |
aws_secretsmanager_secret.fixed | resource |
aws_secretsmanager_secret.placeholder | resource |
aws_secretsmanager_secret_version.fixed | resource |
aws_ssm_parameter.placeholder | resource |
aws_ssm_parameter.this | resource |
aws_volume_attachment.this | resource |
random_password.secrets | resource |
random_password.this | resource |
aws_ami.this | data source |
aws_caller_identity.current | data source |
aws_ec2_instance_type.this | data source |
aws_iam_policy_document.ssm_params_and_secrets | data source |
aws_route53_zone.external | data source |
aws_route53_zone.internal | data source |
cloudinit_config.this | data source |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
<a name="input_account_ids_lookup"></a> account_ids_lookup | A map of account names to account ids that can be used for AMI owner | map(any) | {} | no |
<a name="input_ami_name"></a> ami_name | Name of AMI to be used to launch the database ec2 instance | string | n/a | yes |
<a name="input_ami_owner"></a> ami_owner | Owner of AMI to be used to launch the database ec2 instance | string | "self" | no |
<a name="input_application_name"></a> application_name | The name of the application. This will be name of the environment in Modernisation Platform | string | "nomis" | no |
<a name="input_availability_zone"></a> availability_zone | The availability zone in which to deploy the infrastructure | string | "eu-west-2a" | no |
<a name="input_business_unit"></a> business_unit | This corresponds to the VPC in which the application resides | string | "hmpps" | no |
<a name="input_cloudwatch_metric_alarms"></a> cloudwatch_metric_alarms | Map of cloudwatch metric alarms. The alarm name is set to the ec2 instance name plus the map key. | <pre>map(object({<br/> comparison_operator = string<br/> evaluation_periods = number<br/> metric_name = string<br/> namespace = string<br/> period = number<br/> statistic = string<br/> threshold = number<br/> alarm_actions = list(string)<br/> ok_actions = optional(list(string), [])<br/> actions_enabled = optional(bool, false)<br/> alarm_description = optional(string)<br/> datapoints_to_alarm = optional(number)<br/> treat_missing_data = optional(string, "missing")<br/> dimensions = optional(map(string), {})<br/> }))</pre> | {} | no |
<a name="input_ebs_kms_key_id"></a> ebs_kms_key_id | KMS Key to use for EBS volumes if not explicitly set in ebs_volumes variable | string | null | no |
<a name="input_ebs_volume_config"></a> ebs_volume_config | EC2 volume configurations, where key is a label, e.g. flash, which is assigned to the disk in ebs_volumes. All disks with same label have the same configuration. If not specified, use values from the AMI. If total_size specified, the volume size is this divided by the number of drives with the given label | <pre>map(object({<br/> iops = optional(number)<br/> throughput = optional(number)<br/> total_size = optional(number)<br/> type = optional(string)<br/> kms_key_id = optional(string)<br/> }))</pre> | n/a | yes |
<a name="input_ebs_volume_tags"></a> ebs_volume_tags | Additional tags to apply to ebs volumes | map(string) | {} | no |
<a name="input_ebs_volumes"></a> ebs_volumes | EC2 volumes, see aws_ebs_volume for documentation. key=volume name, value=ebs_volume_config key. label is used as part of the Name tag | <pre>map(object({<br/> label = optional(string)<br/> snapshot_id = optional(string)<br/> iops = optional(number)<br/> throughput = optional(number)<br/> size = optional(number)<br/> type = optional(string)<br/> kms_key_id = optional(string)<br/> }))</pre> | n/a | yes |
<a name="input_ebs_volumes_copy_all_from_ami"></a> ebs_volumes_copy_all_from_ami | If true, ensure all volumes in AMI are also present in EC2. If false, only create volumes specified in ebs_volumes var | bool | true | no |
<a name="input_environment"></a> environment | Application environment - i.e. the terraform workspace | string | n/a | yes |
<a name="input_iam_resource_names_prefix"></a> iam_resource_names_prefix | Prefix IAM resources with this prefix, e.g. ec2-database | string | "ec2" | no |
<a name="input_instance"></a> instance | EC2 instance settings, see aws_instance documentation | <pre>object({<br/> associate_public_ip_address = optional(bool, false)<br/> disable_api_termination = bool<br/> disable_api_stop = bool<br/> instance_type = string<br/> key_name = string<br/> metadata_endpoint_enabled = optional(string, "enabled")<br/> metadata_options_http_tokens = optional(string, "required")<br/> monitoring = optional(bool, true)<br/> ebs_block_device_inline = optional(bool, false)<br/> vpc_security_group_ids = list(string)<br/> private_dns_name_options = optional(object({<br/> enable_resource_name_dns_aaaa_record = optional(bool)<br/> enable_resource_name_dns_a_record = optional(bool)<br/> hostname_type = string<br/> }))<br/> tags = optional(map(string), {})<br/> })</pre> | n/a | yes |
<a name="input_instance_profile_policies"></a> instance_profile_policies | A list of managed IAM policy document ARNs to be attached to the database instance profile | list(string) | n/a | yes |
<a name="input_name"></a> name | Provide a unique name for the instance | string | n/a | yes |
<a name="input_region"></a> region | Destination AWS Region for the infrastructure | string | "eu-west-2" | no |
<a name="input_route53_records"></a> route53_records | Optionally create internal and external DNS records | <pre>object({<br/> create_internal_record = bool<br/> create_external_record = bool<br/> })</pre> | n/a | yes |
<a name="input_secretsmanager_secrets"></a> secretsmanager_secrets | A map of secretsmanager secrets to create. Set a specific value or a randomly generated value. If neither random or value are set, a placeholder value is created which can be updated outside of terraform | <pre>map(object({<br/> description = optional(string)<br/> kms_key_id = optional(string)<br/> recovery_window_in_days = optional(number)<br/> random = optional(object({<br/> length = number<br/> special = optional(bool)<br/> }))<br/> value = optional(string)<br/> }))</pre> | null | no |
<a name="input_secretsmanager_secrets_prefix"></a> secretsmanager_secrets_prefix | Optionally prefix secretsmanager secrets with this prefix. Add a trailing / | string | "" | no |
<a name="input_ssm_parameters"></a> ssm_parameters | A map of SSM parameters to create. Set a specific value or a randomly generated value. If neither random or value are set, a placeholder value is created which can be updated outside of terraform | <pre>map(object({<br/> description = optional(string)<br/> type = optional(string, "SecureString")<br/> kms_key_id = optional(string)<br/> random = optional(object({<br/> length = number<br/> special = optional(bool)<br/> }))<br/> value = optional(string)<br/> }))</pre> | null | no |
<a name="input_ssm_parameters_prefix"></a> ssm_parameters_prefix | Optionally prefix ssm parameters with this prefix. Add a trailing / | string | "" | no |
<a name="input_subnet_id"></a> subnet_id | The subnet id in which to deploy the infrastructure | string | n/a | yes |
<a name="input_tags"></a> tags | Default tags to be applied to resources. Additional tags can be added to EBS volumes or EC2s, see instance.tags and ebs_volume_tags variables. | map(any) | n/a | yes |
<a name="input_user_data_cloud_init"></a> user_data_cloud_init | Use this instead of user_data_raw to run multiple scripts using cloud_init | <pre>object({<br/> args = optional(map(string))<br/> scripts = optional(list(string))<br/> write_files = optional(map(object({<br/> path = string<br/> owner = string<br/> permissions = string<br/> })), {})<br/> })</pre> | null | no |
<a name="input_user_data_raw"></a> user_data_raw | Base64 encoded user data, script or cloud formation template | string | null | no |
Outputs
Name | Description |
---|---|
<a name="output_aws_ebs_volume"></a> aws_ebs_volume | aws_ebs_volume resource |
<a name="output_aws_instance"></a> aws_instance | aws_instance resource |