Reusable Terraform module to deploy a secure, SSM-enabled EC2 jumphost in AWS
- Multi-OS Support: Amazon Linux 2/2023, Ubuntu 20.04, RHEL 8/9
- SSM Integration: Automatic SSM Agent installation and IAM permissions
- EC2 Instance Connect: Optional EC2 Instance Connect support for SSH access
- Security: Configurable security groups, encrypted volumes, IMDSv2
- Flexible Deployment: Public or private subnets with optional EIP
- Red Hat Support: Enhanced RHEL 8/9 support with repository management
For RHEL instances, the module includes enhanced support:
- Automatic SSM Agent: Installs and configures AWS Systems Manager Agent using multiple fallback methods
- Repository Management: Optional Red Hat repository activation via
enable_redhat_repos - Robust Installation: Multiple installation methods ensure packages are installed regardless of Red Hat registration status
- Better Error Handling: Improved logging and error recovery
The module uses a multi-method approach to ensure packages are installed:
- Default Repositories: First tries to install from the repositories available in the RHEL AMI
- EPEL Repository: Falls back to EPEL if packages aren't in default repositories
- AWS S3 Download: Downloads packages directly from AWS S3 if repository installation fails
- Alternative Package Names: Tries alternative package names as a last resort
This approach ensures that SSM Agent and EC2 Instance Connect are installed regardless of whether the instance is registered with Red Hat or not.
The enable_redhat_repos variable provides optional Red Hat repository support:
- When enabled: Attempts to enable Red Hat repositories if the instance is registered
- When disabled or unregistered: Uses default repositories that come with RHEL AMIs
- Graceful fallback: Continues with available repositories if Red Hat repositories are not accessible
module "jumphost" {
source = "path/to/module"
ami_type = "rhel9"
enable_redhat_repos = true # Optional: enables Red Hat repos if registered
# ... other configuration
}| Name | Version |
|---|---|
| terraform | >= 1.3.0 |
| aws | >= 6.0 |
| Name | Version |
|---|---|
| aws | 6.9.0 |
No modules.
| Name | Type |
|---|---|
| aws_ec2_instance_connect_endpoint.this | resource |
| aws_eip.this | resource |
| aws_iam_instance_profile.this | resource |
| aws_iam_role.this | resource |
| aws_iam_role_policy_attachment.cw_agent | resource |
| aws_iam_role_policy_attachment.ssm_core | resource |
| aws_instance.this | resource |
| aws_security_group.this | resource |
| aws_ami.selected | data source |
| aws_iam_policy_document.ec2_assume | data source |
| aws_region.current | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| allowed_cidr_blocks | List of CIDR ranges allowed to connect via SSH when create_security_group = true. | list(string) |
[ |
no |
| ami_id_override | Optional explicit AMI ID to use instead of automatic lookup. | string |
"" |
no |
| ami_type | Logical AMI type to use. Allowed: amazonlinux2, amazonlinux2023, ubuntu, rhel8, rhel9. | string |
"amazonlinux2" |
no |
| assign_eip | Whether to allocate and associate an Elastic IP (valid only when subnet is public). | bool |
true |
no |
| create | Whether to create resources. Set to false to disable the module entirely. | bool |
true |
no |
| create_security_group | Create a dedicated security group allowing SSH/ICMP from allowed CIDRs if no security group IDs are supplied. If true, vpc_security_group_ids can be empty. | bool |
false |
no |
| enable_cloudwatch_agent | Install CloudWatch agent and push system logs/metrics. | bool |
false |
no |
| enable_instance_connect | Install and enable EC2 Instance Connect for SSH (Amazon Linux & Ubuntu only). | bool |
false |
no |
| enable_instance_connect_endpoint | Create an EC2 Instance Connect Endpoint for private subnet access (requires VPC endpoints or NAT). | bool |
false |
no |
| enable_redhat_repos | Enable Red Hat repositories for RHEL instances (requires manual registration after deployment). If false, uses default repositories that come with RHEL AMIs. | bool |
false |
no |
| enable_ssm | Enable SSM Agent and permissions via instance profile. | bool |
true |
no |
| iam_instance_profile_name | Existing IAM instance profile to attach instead of creating one. | string |
"" |
no |
| instance_connect_endpoint_subnet_id | Subnet ID for the EC2 Instance Connect Endpoint (should be private with NAT or VPC endpoints). | string |
"" |
no |
| instance_type | EC2 instance type. | string |
"t3.micro" |
no |
| kms_key_id | KMS key ID for EBS encryption (optional). | string |
"" |
no |
| name | Base name used for resource naming and tagging. | string |
"jumphost" |
no |
| patch_and_reboot | If true, the instance will perform OS update and automatically reboot once during user_data. | bool |
false |
no |
| root_volume_encrypted | Whether the root EBS volume should be encrypted. | bool |
true |
no |
| root_volume_size | Root EBS volume size in GiB. | number |
20 |
no |
| root_volume_type | Root EBS volume type. | string |
"gp3" |
no |
| subnet_id | Subnet ID in which to launch the instance (public or private with outbound internet/SSM access). | string |
n/a | yes |
| tags | Additional tags to apply to all resources. | map(string) |
{} |
no |
| user_data_extra | Additional user_data shell commands appended to the module's base user_data. | string |
"" |
no |
| user_data_override | Completely override the generated user_data with your own script (cloud-init or shell). | string |
"" |
no |
| vpc_id | Optional VPC ID – used only for tagging or looking up endpoints. | string |
"" |
no |
| vpc_security_group_ids | List of security group IDs to attach to the instance. | list(string) |
[] |
no |
| Name | Description |
|---|---|
| iam_instance_profile_arn | ARN of the IAM instance profile created for the jumphost (if created). |
| iam_instance_profile_name | Name of the IAM instance profile created for the jumphost (if created). |
| iam_role_arn | ARN of the IAM role created for the jumphost (if created). |
| iam_role_name | Name of the IAM role created for the jumphost (if created). |
| instance_connect_command | Convenience AWS CLI command to connect via EC2 Instance Connect (when enabled). |
| instance_connect_endpoint_dns_name | DNS name of the EC2 Instance Connect Endpoint (if created). |
| instance_connect_endpoint_id | ID of the EC2 Instance Connect Endpoint (if created). |
| instance_id | ID of the jumphost instance. |
| private_ip | Private IP address of the instance. |
| public_dns | Public DNS name of the instance, if available. |
| public_ip | Public IP address (or EIP) of the instance, if assigned. |
| security_group_id | ID of the created security group (if any). |
| ssm_session_command | Convenience AWS CLI command to open an SSM session to the instance. |