Skip to main content
Module Server 0.15.13Last updated in version 0.15.13

Single Server Module

View SourceRelease Notes

This module makes it easy to deploy a single server--that is, a single EC2 instance (e.g. a bastion host, Jenkins server) rather than an Auto Scaling Group or ECS Cluster--along with the all the resources it typically needs:

  1. The EC2 instance itself.
  2. An Elastic IP (EIP) address.
  3. An optional DNS record pointing at the EIP.
  4. IAM Role and IAM instance profile.
  5. Security group.

How do I see the server?

This module includes several Terraform outputs, including:

  1. public_ip: The public IP address of the server (via its EIP)
  2. fqdn: The fully-qualified domain name of the server (e.g. jenkins.example.com) if you set the dns_zone_id and dns_name variables.

Can I BYOSG (bring your own security groups)?

In some cases, it's desirable to have the ability to assign your own externally managed security groups. To do this, set the additional_security_group_ids variable with the desired security group id(s). This list of security groups will be combined with the default security group.

Note: if you set default_network_interface_id to override the default network interface, AWS does not allow attaching any security groups to the EC2 instance, so you will need to attach any and all security groups you need to the network interface you pass in.

What if I just want to add custom security group rules to the default security group?

One of the other important outputs of this module is the security_group_id, which is the id of the server's default Security Group. You can add custom rules to this Security Group using the aws_security_group_rule resource:

module "jenkins" {
source = "git::git@github.com:gruntwork-io/terraform-aws-server.git//modules/single-server?ref=v0.0.40"

# (... options omitted...)
}

# Custom rule to allow inbound HTTPS traffic from anywhere
resource "aws_security_group_rule" "allow_inbound_https_all" {
type = "ingress"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = "${module.jenkins.security_group_id}"
}

How do I add a custom IAM policy?

This module creates an IAM role for your EC2 instance and exports the id of that role as the output iam_role_id. You can attach custom policies to this IAM role using the aws_iam_policy_attachment resource:

module "jenkins" {
source = "git::git@github.com:gruntwork-io/terraform-aws-server.git//modules/single-server?ref=v0.0.40"

# (... options omitted...)
}

resource "aws_iam_policy" "my_custom_policy" {
name = "my-custom-policy"
policy = " (... omitted ...) "
}

resource "aws_iam_policy_attachment" "attachment" {
name = "example-attachment"
roles = ["${module.jenkins.iam_role_id}"]
policy_arn = "${aws_iam_policy.my_custom_policy.arn}"
}

Sample Usage

main.tf

# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S SINGLE-SERVER MODULE
# ------------------------------------------------------------------------------------------------------

module "single_server" {

source = "git::git@github.com:gruntwork-io/terraform-aws-server.git//modules/single-server?ref=v0.15.13"

# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------

# The ID of the AMI to run for this server.
ami = <string>

# The type of EC2 instance to run (e.g. t2.micro)
instance_type = <string>

# The name of a Key Pair that can be used to SSH to this instance. Leave blank
# if you don't want to enable Key Pair auth.
keypair_name = <string>

# The name of the server. This will be used to namespace all resources created
# by this module.
name = <string>

# The id of the subnet where this server should be deployed. Required unless
# default_network_interface_id is set, in which case subnet_id should be set
# to null.
subnet_id = <string>

# The id of the VPC where this server should be deployed.
vpc_id = <string>

# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------

# A list of optional additional security group ids to assign to the server.
# Note: this variable is NOT used if default_network_interface_id is set.
additional_security_group_ids = []

# A boolean that specifies whether or not to add a security group rule that
# allows all outbound traffic from this server.
allow_all_outbound_traffic = true

# A list of IP address ranges in CIDR format from which rdp access will be
# permitted. Attempts to access the bastion host from all other IP addresses
# will be blocked.
allow_rdp_from_cidr_list = []

# A list of IPv6 address ranges in CIDR format from which rdp access will be
# permitted. Attempts to access the bastion host from all other IP addresses
# will be blocked.
allow_rdp_from_ipv6_cidr_list = []

# The IDs of security groups from which rdp connections will be allowed.
allow_rdp_from_security_group_ids = []

# A list of IP address ranges in CIDR format from which SSH access will be
# permitted. Attempts to access the server from all other IP addresses will be
# blocked.
allow_ssh_from_cidr_list = ["0.0.0.0/0"]

# A list of IPv6 address ranges in CIDR format from which SSH access will be
# permitted. Attempts to access the server from all other IP addresses will be
# blocked.
allow_ssh_from_ipv6_cidr_list = []

# The IDs of security groups from which SSH connections will be allowed.
allow_ssh_from_security_group_ids = []

# Whether or not to associate a public IP address to the instance. When null,
# defaults to the subnet setting (e.g., if public subnet defaults to
# associating a public IP, associate one - otherwise, does not associate a
# public IP).
associate_public_ip_address = null

# A list of AWS service principals that can assume the instance IAM role. If
# deploying in AWS China, set this to [ec2.amazonaws.com.cn].
assume_role_principals = ["ec2.amazonaws.com"]

# Determines if an Elastic IP (EIP) will be created for this instance. Must be
# set to a boolean (not a string!) true or false value.
attach_eip = true

# When true, this module will create a new IAM role to bind to the EC2
# instance. Set to false if you wish to use a preexisting IAM role. By
# default, this module will create an instance profile to pass this IAM role
# to the EC2 instance. Preexisting IAM roles created through the AWS console
# instead of programatically (e.g. withTerraform) will automatically create an
# instance profile with the same name. In that case, set
# create_instance_profile to false to avoid errors during Terraform apply.
create_iam_role = true

# When true, this module will create an instance profile to pass the IAM role,
# either the one created by this module or one passed externally, to the EC2
# instance. Set to false if you wish to use a preexisting instance profile.
# For more information see
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html.
create_instance_profile = true

# ID of a dedicated host that the instance will be assigned to. Use when an
# instance is to be launched on a specific dedicated host.
dedicated_host_id = null

# The ID of a network interface to use to override the default network
# interface for this EC2 instance, attached at eth0 (device index 0). If set,
# subnet_id must be set to null.
default_network_interface_id = null

# If true, enables EC2 Instance Termination Protection.
disable_api_termination = false

# The DNS name to add for this server in var.dns_zone_id. Only used if
# var.dns_zone_id is set. For example, if var.dns_zone_id points to the hosted
# zone for example.com and you set dns_name to foo, this server will have the
# domain foo.example.com.
dns_name = ""

# The TTL, in seconds, of the DNS record for this server. Only used if
# var.dns_zone_id is set.
dns_ttl = 300

# The DNS record type when adding a DNS record for this server. Only used if
# var.dns_zone_id is set.
dns_type = "A"

# If set to true, point the Route 53 DNS record at the private IP of the EIP
# rather than the public IP.
dns_uses_private_ip = false

# The id of a route53 hosted zone. Leave blank if you don't want a DNS entry
# for this server. If you specify this variable, you must also specify
# var.dns_name.
dns_zone_id = ""

# If true, the launced EC2 Instance will be EBS-optimized.
ebs_optimized = false

# A set of tags to set for the EIP for EC2 Instance. This is optional and if
# not provided the tags from variable tags will be used
eip_tags = {}

# Whether to force detaching any policies the role has before destroying it.
# If policies are attached to the role via the aws_iam_policy_attachment
# resource and you are modifying the role name or path, the
# force_detach_policies argument must be set to true and applied before
# attempting the operation otherwise you will encounter a DeleteConflict
# error. The aws_iam_role_policy_attachment resource (recommended) does not
# have this requirement.
force_detach_policies = false

# Whether or not to extract Base-64 encoded encrypted password data for the
# instance. Useful for getting the administrator password for instances
# running Microsoft Windows.
get_password_data = false

# The name for the bastion host's IAM role and instance profile. If set to an
# empty string, will use var.name. Required when create_iam_role is false.
iam_role_name = ""

# A set of tags to set for instance iam role. This is optional and if not
# provided the tags from variable tags will be used
iam_role_tags = {}

# A set of tags for EC2 Instance. This is optional and if not provided the
# tags from variable tags will be used
instance_tags = {}

# Whether the metadata service is available. Valid values include enabled or
# disabled. Defaults to enabled.
metadata_http_endpoint = "enabled"

# Desired HTTP PUT response hop limit for instance metadata requests. The
# larger the number, the further instance metadata requests can travel. Valid
# values are integer from 1 to 64. Defaults to 1.
metadata_http_put_response_hop_limit = 1

# Whether or not the metadata service requires session tokens, also referred
# to as Instance Metadata Service Version 2 (IMDSv2). Valid values include
# optional or required. Defaults to optional.
metadata_http_tokens = "optional"

# Enables or disables access to instance tags from the instance metadata
# service. Valid values include enabled or disabled. Defaults to disabled.
metadata_tags = "disabled"

# If true, the launched EC2 instance will have detailed monitoring enabled.
monitoring = false

# Private IP address to associate with the instance in a VPC
private_ip = null

# Instruct Terraform to revoke all of the Security Groups attached ingress and
# egress rules before deleting the rule itself. This is normally not needed,
# however certain AWS services such as Elastic Map Reduce may automatically
# add required rules to security groups used with the service, and those rules
# may contain a cyclic dependency that prevent the security groups from being
# destroyed without removing the dependency first.
revoke_security_group_rules_on_delete = false

# The ARN of the policy that is used to set the permissions boundary for the
# IAM role.
role_permissions_boundary = null

# If set to true, the root volume will be deleted when the Instance is
# terminated.
root_volume_delete_on_termination = true

# If set to true, the root volume will be encrypted. Default is set to false
root_volume_encrypted = false

# The size of the root volume, in gigabytes.
root_volume_size = 8

# Tags to set on the root volume.
root_volume_tags = {}

# The root volume type. Must be one of: standard, gp2, io1.
root_volume_type = "standard"

# A list of secondary private IPv4 addresses to assign to the instance's
# primary network interface (eth0) in a VPC
secondary_private_ips = null

# The name for the bastion host's security group. If set to an empty string,
# will use var.name.
security_group_name = ""

# A set of tags to set for the Security Group. This is optional and if not
# provided the tags from variable tags will be used
security_group_tags = {}

# Controls if traffic is routed to the instance when the destination address
# does not match the instance. Must be set to a boolean (not a string!) true
# or false value.
source_dest_check = true

# A set of tags for the EC2 Instance. These are common tags and will be used
# for Instance, IAM Role, EIP and Security Group. Note that other AWS
# resources created by this module such as an Elastic IP Address and Route53
# Record do not support tags.
tags = {}

# The tenancy of this server. Must be one of: default, dedicated, or host.
tenancy = "default"

# The User Data script to run on this instance when it is booting. If you need
# to pass gzipped, base64-encoded data (e.g., for a cloud-init script), use
# var.user_data_base64 instead.
user_data = null

# The base64-encoded User Data script to run on the server when it is booting.
# This can be used to pass binary User Data, such as a gzipped cloud-init
# script. If you wish to pass in plain text (e.g., typical Bash script) for
# User Data, use var.user_data instead.
user_data_base64 = null

# When used in combination with user_data or user_data_base64, a user_data
# change will trigger a destroy and recreate when set to true. Defaults to
# null.
user_data_replace_on_change = null

}


Reference

Required

amistringrequired

The ID of the AMI to run for this server.

instance_typestringrequired

The type of EC2 instance to run (e.g. t2.micro)

keypair_namestringrequired

The name of a Key Pair that can be used to SSH to this instance. Leave blank if you don't want to enable Key Pair auth.

namestringrequired

The name of the server. This will be used to namespace all resources created by this module.

subnet_idstringrequired

The id of the subnet where this server should be deployed. Required unless default_network_interface_id is set, in which case subnet_id should be set to null.

vpc_idstringrequired

The id of the VPC where this server should be deployed.

Optional

additional_security_group_idslist(string)optional

A list of optional additional security group ids to assign to the server. Note: this variable is NOT used if default_network_interface_id is set.

[]

A boolean that specifies whether or not to add a security group rule that allows all outbound traffic from this server.

true
allow_rdp_from_cidr_listlist(string)optional

A list of IP address ranges in CIDR format from which rdp access will be permitted. Attempts to access the bastion host from all other IP addresses will be blocked.

[]
allow_rdp_from_ipv6_cidr_listlist(string)optional

A list of IPv6 address ranges in CIDR format from which rdp access will be permitted. Attempts to access the bastion host from all other IP addresses will be blocked.

[]

The IDs of security groups from which rdp connections will be allowed.

[]
allow_ssh_from_cidr_listlist(string)optional

A list of IP address ranges in CIDR format from which SSH access will be permitted. Attempts to access the server from all other IP addresses will be blocked.

[ "0.0.0.0/0" ]
allow_ssh_from_ipv6_cidr_listlist(string)optional

A list of IPv6 address ranges in CIDR format from which SSH access will be permitted. Attempts to access the server from all other IP addresses will be blocked.

[]

The IDs of security groups from which SSH connections will be allowed.

[]

Whether or not to associate a public IP address to the instance. When null, defaults to the subnet setting (e.g., if public subnet defaults to associating a public IP, associate one - otherwise, does not associate a public IP).

null
assume_role_principalslist(string)optional

A list of AWS service principals that can assume the instance IAM role. If deploying in AWS China, set this to [ec2.amazonaws.com.cn].

[
"ec2.amazonaws.com"
]
attach_eipbooloptional

Determines if an Elastic IP (EIP) will be created for this instance. Must be set to a boolean (not a string!) true or false value.

true
create_iam_rolebooloptional

When true, this module will create a new IAM role to bind to the EC2 instance. Set to false if you wish to use a preexisting IAM role. By default, this module will create an instance profile to pass this IAM role to the EC2 instance. Preexisting IAM roles created through the AWS console instead of programatically (e.g. withTerraform) will automatically create an instance profile with the same name. In that case, set create_instance_profile to false to avoid errors during Terraform apply.

true

When true, this module will create an instance profile to pass the IAM role, either the one created by this module or one passed externally, to the EC2 instance. Set to false if you wish to use a preexisting instance profile. For more information see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html.

true
dedicated_host_idstringoptional

ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host.

null

The ID of a network interface to use to override the default network interface for this EC2 instance, attached at eth0 (device index 0). If set, subnet_id must be set to null.

null

If true, enables EC2 Instance Termination Protection.

false
dns_namestringoptional

The DNS name to add for this server in dns_zone_id. Only used if dns_zone_id is set. For example, if dns_zone_id points to the hosted zone for example.com and you set dns_name to foo, this server will have the domain foo.example.com.

""
dns_ttlnumberoptional

The TTL, in seconds, of the DNS record for this server. Only used if dns_zone_id is set.

300
dns_typestringoptional

The DNS record type when adding a DNS record for this server. Only used if dns_zone_id is set.

"A"

If set to true, point the Route 53 DNS record at the private IP of the EIP rather than the public IP.

false
dns_zone_idstringoptional

The id of a route53 hosted zone. Leave blank if you don't want a DNS entry for this server. If you specify this variable, you must also specify dns_name.

""
ebs_optimizedbooloptional

If true, the launced EC2 Instance will be EBS-optimized.

false
eip_tagsmap(string)optional

A set of tags to set for the EIP for EC2 Instance. This is optional and if not provided the tags from variable tags will be used

{}
force_detach_policiesstringoptional

Whether to force detaching any policies the role has before destroying it. If policies are attached to the role via the aws_iam_policy_attachment resource and you are modifying the role name or path, the force_detach_policies argument must be set to true and applied before attempting the operation otherwise you will encounter a DeleteConflict error. The aws_iam_role_policy_attachment resource (recommended) does not have this requirement.

false
get_password_databooloptional

Whether or not to extract Base-64 encoded encrypted password data for the instance. Useful for getting the administrator password for instances running Microsoft Windows.

false
iam_role_namestringoptional

The name for the bastion host's IAM role and instance profile. If set to an empty string, will use name. Required when create_iam_role is false.

""
iam_role_tagsmap(string)optional

A set of tags to set for instance iam role. This is optional and if not provided the tags from variable tags will be used

{}
instance_tagsmap(string)optional

A set of tags for EC2 Instance. This is optional and if not provided the tags from variable tags will be used

{}

Whether the metadata service is available. Valid values include enabled or disabled. Defaults to enabled.

"enabled"

Desired HTTP PUT response hop limit for instance metadata requests. The larger the number, the further instance metadata requests can travel. Valid values are integer from 1 to 64. Defaults to 1.

1
metadata_http_tokensstringoptional

Whether or not the metadata service requires session tokens, also referred to as Instance Metadata Service Version 2 (IMDSv2). Valid values include optional or required. Defaults to optional.

"optional"
metadata_tagsstringoptional

Enables or disables access to instance tags from the instance metadata service. Valid values include enabled or disabled. Defaults to disabled.

"disabled"
monitoringbooloptional

If true, the launched EC2 instance will have detailed monitoring enabled.

false
private_ipstringoptional

Private IP address to associate with the instance in a VPC

null

Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. This is normally not needed, however certain AWS services such as Elastic Map Reduce may automatically add required rules to security groups used with the service, and those rules may contain a cyclic dependency that prevent the security groups from being destroyed without removing the dependency first.

false

The ARN of the policy that is used to set the permissions boundary for the IAM role.

null

If set to true, the root volume will be deleted when the Instance is terminated.

true

If set to true, the root volume will be encrypted. Default is set to false

false
root_volume_sizenumberoptional

The size of the root volume, in gigabytes.

8
root_volume_tagsmap(string)optional

Tags to set on the root volume.

{}
root_volume_typestringoptional

The root volume type. Must be one of: standard, gp2, io1.

"standard"
secondary_private_ipslist(string)optional

A list of secondary private IPv4 addresses to assign to the instance's primary network interface (eth0) in a VPC

null
security_group_namestringoptional

The name for the bastion host's security group. If set to an empty string, will use name.

""
security_group_tagsmap(string)optional

A set of tags to set for the Security Group. This is optional and if not provided the tags from variable tags will be used

{}
source_dest_checkbooloptional

Controls if traffic is routed to the instance when the destination address does not match the instance. Must be set to a boolean (not a string!) true or false value.

true
tagsmap(string)optional

A set of tags for the EC2 Instance. These are common tags and will be used for Instance, IAM Role, EIP and Security Group. Note that other AWS resources created by this module such as an Elastic IP Address and Route53 Record do not support tags.

{}
tenancystringoptional

The tenancy of this server. Must be one of: default, dedicated, or host.

"default"
user_datastringoptional

The User Data script to run on this instance when it is booting. If you need to pass gzipped, base64-encoded data (e.g., for a cloud-init script), use user_data_base64 instead.

null
user_data_base64stringoptional

The base64-encoded User Data script to run on the server when it is booting. This can be used to pass binary User Data, such as a gzipped cloud-init script. If you wish to pass in plain text (e.g., typical Bash script) for User Data, use user_data instead.

null

When used in combination with user_data or user_data_base64, a user_data change will trigger a destroy and recreate when set to true. Defaults to null.

null