You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* make egress and service ports configurable; create example
* fix formatting, obsolete explicit manual dependencies
* fix up documentation for 8.1 release
Copy file name to clipboardExpand all lines: README.md
+17-16Lines changed: 17 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,6 @@
1
1
# This Terraform deploys a stateless containerised sshd bastion service on AWS with IAM based authentication:
2
2
3
-
**This module requires Terraform >/=0.15/1.x.x**
4
-
5
-
- Terraform 0.13.x was _previously_ supported with module version to ~> v6.1
6
-
- Terraform 0.12.x was _previously_ supported with module version to ~> v5.0
7
-
- Terraform 0.11.x was _previously_ supported with module version to ~> v4.0
3
+
This module requires Terraform >/=1.2.0 Older versions were previously supported going back to Terraform 0.11.x with module version to ~> v4.0
8
4
9
5
**N.B. If you are using a newer version of this module when you have an older version deployed, please review the changelog!**
10
6
@@ -26,7 +22,9 @@ You may find it more convenient to call it in your plan [directly from the Terra
26
22
27
23
# Quick start
28
24
29
-
Ivan Mesic has kindly contributed an example use of this module creating a VPC and a bastion instance within it - see `/examples`
25
+
Ivan Mesic has kindly contributed an example use of this module creating a VPC and a bastion instance within it - see `/examples/full-with-public-ip`
26
+
27
+
`examples/custom-outbound-security-group` is for more specialist use cases demonstrating how to run the service on a different port with an external supplied security group for external ingress and egress. This would not be necessary for most users.
30
28
31
29
# Custom sections:
32
30
@@ -48,6 +46,12 @@ The variables for these sections are:
48
46
49
47
If you exclude any section then you must replace it with equivalent functionality, either in your base AMI or `extra_user_data*` for a working service. Especially if you are not replacing all sections then be mindful that the systemd service expects docker to be installed and to be able to call the docker container as `sshd_worker`. The service container in turn references the `ssh_populate` script which calls `iam-authorized-keys` from a specific location.
50
48
49
+
You can **supply a list of one or more security groups to attach to the host instance launch configuration** within the module if you wish. This can be supplied together with or instead of a whitelisted range of CIDR blocks. Starting with release 8.1 it is possible to use this to also passlist egress ports **exclusively** if `var.custom_outbound_security_group = true` (default false). It may be useful in an enterprise setting to have security groups with rules managed separately from the bastion plan but of course if you do not assign either a suitable security group or whitelist then you may not be able to reach the service!
50
+
51
+
Starting with release 8.1 it is possible to **assign a custom port for the containerised ssh bastion service**, e.g. port 443. This may be useful for advanced users and must match security group ingress and egress- see `examples/custom-outbound-security-group`
52
+
53
+
**Load Balancer health check port may be optionally set to either the containerised service port (by default port 22) or port 2222 (EC2 host sshd)**. Port 2222 is the default. If you are deploying a large number of bastion instances, all of them checking into the same parent account for IAM queries in response to load balancer health checks on port 22 causes IAM rate limiting from AWS. Using the modified EC2 host sshd of port 2222 avoids this issue, is recommended for larger deployments and is now default. The host sshd is set to port 2222 as part of the service setup so this healthcheck is not entirely invalid. Security group rules, target groups and load balancer listeners are conditionally created to support any combination of access/healthcheck on port 2222 or not.
54
+
51
55
# Ability to assume a role in another account
52
56
53
57
The ability to assume a role to source IAM users from another account has been integrated with conditional logic. If you supply the ARN for a role for the bastion service to assume (typically in another account) ${var.assume_role_arn} then this plan will create an instance profile, role and policy along with each bastion to make use of it. A matching sample policy and trust relationship is given as an output from the plan to assist with application in the other account. If you do not supply this arn then this plan presumes IAM lookups in the same account and creates an appropriate instance profile, role and policies for each bastion in the same AWS account. 'Each bastion' here refers to a combination of environment, AWS account, AWS region and VPCID determined by deployment. This is a high availability service, but if you are making more than one independent deployment using this same module within such a combination then you can specify "service_name" to avoid resource collision.
@@ -205,12 +209,6 @@ Starting with release 3.8 it is possible to use the output giving the name of th
205
209
206
210
- ssh keys are called only at login- if an account or ssh public key is deleted from AWS whilst a user is logged in then that session will continue until otherwise terminated.
207
211
208
-
# Notes for deployment
209
-
210
-
Load Balancer health check port may be optionally set to either port 22 (containerised service) or port 2222 (EC2 host sshd). Port 2222 is the default. If you are deploying a large number of bastion instances, all of them checking into the same parent account for IAM queries in response to load balancer health checks on port 22 causes IAM rate limiting from AWS. Using the modified EC2 host sshd of port 2222 avoids this issue, is recommended for larger deployments and is now default. The host sshd is set to port 2222 as part of the service setup so this healthcheck is not entirely invalid. Security group rules, target groups and load balancer listeners are conditionally created to support any combination of access/healthcheck on port 2222 or not.
211
-
212
-
You can supply list of one or more security groups to attach to the host instance launch configuration within the module if you wish. This can be supplied together with or instead of a whitelisted range of CIDR blocks. It may be useful in an enterprise setting to have security groups with rules managed separately from the bastion plan but of course if you do not assign either a suitable security group or whitelist then you may not be able to reach the service!
213
-
214
212
## Components (using default userdata)
215
213
216
214
**EC2 Host OS (debian) with:**
@@ -260,6 +258,7 @@ The DNS entry (if created) for the service is also displayed as an output of the
260
258
```terraform
261
259
name = "${var.environment_name}-${data.aws_region.current.name}-${var.vpc}-bastion-service.${var.dns_domain}"
262
260
```
261
+
263
262
## Inputs and Outputs
264
263
265
264
These have been generated with [terraform-docs](https://github.com/segmentio/terraform-docs)
@@ -268,14 +267,14 @@ These have been generated with [terraform-docs](https://github.com/segmentio/ter
| <aname="input_bastion_host_name"></a> [bastion\_host\_name](#input\_bastion\_host\_name)| The hostname to give to the bastion instance |`string`|`""`| no |
334
333
| <aname="input_bastion_instance_types"></a> [bastion\_instance\_types](#input\_bastion\_instance\_types)| List of ec2 types for the bastion host, used by aws\_launch\_template (first from the list) and in aws\_autoscaling\_group |`list`| <pre>[<br> "t3.small",<br> "t3.medium",<br> "t3.large"<br>]</pre> | no |
335
334
| <aname="input_bastion_service_host_key_name"></a> [bastion\_service\_host\_key\_name](#input\_bastion\_service\_host\_key\_name)| AWS ssh key *.pem to be used for ssh access to the bastion service host |`string`|`""`| no |
335
+
| <aname="input_bastion_service_port"></a> [bastion\_service\_port](#input\_bastion\_service\_port)| Port for containerised ssh daemon |`number`|`22`| no |
336
336
| <aname="input_bastion_vpc_name"></a> [bastion\_vpc\_name](#input\_bastion\_vpc\_name)| define the last part of the hostname, by default this is the vpc ID with magic default value of 'vpc\_id' but you can pass a custom string, or an empty value to omit this |`string`|`"vpc_id"`| no |
337
337
| <aname="input_cidr_blocks_whitelist_host"></a> [cidr\_blocks\_whitelist\_host](#input\_cidr\_blocks\_whitelist\_host)| range(s) of incoming IP addresses to whitelist for the HOST |`list(string)`|`[]`| no |
338
338
| <aname="input_cidr_blocks_whitelist_service"></a> [cidr\_blocks\_whitelist\_service](#input\_cidr\_blocks\_whitelist\_service)| range(s) of incoming IP addresses to whitelist for the SERVICE |`list(string)`|`[]`| no |
339
339
| <aname="input_container_ubuntu_version"></a> [container\_ubuntu\_version](#input\_container\_ubuntu\_version)| ubuntu version to use for service container |`string`|`"22.04"`| no |
340
340
| <aname="input_custom_ami_id"></a> [custom\_ami\_id](#input\_custom\_ami\_id)| id for custom ami if used |`string`|`""`| no |
341
341
| <aname="input_custom_authorized_keys_command"></a> [custom\_authorized\_keys\_command](#input\_custom\_authorized\_keys\_command)| any value excludes default Go binary iam-authorized-keys built from source from userdata |`string`|`""`| no |
342
342
| <aname="input_custom_docker_setup"></a> [custom\_docker\_setup](#input\_custom\_docker\_setup)| any value excludes default docker installation and container build from userdata |`string`|`""`| no |
343
+
| <aname="input_custom_outbound_security_group"></a> [custom\_outbound\_security\_group](#input\_custom\_outbound\_security\_group)| don't create default outgoing permissive security group rule - will only work with custom AMI or if security group supplied with ports 53(UDP); 80(TCP); 443(TCP) open for 0.0.0.0/0 egress |`bool`|`false`| no |
343
344
| <aname="input_custom_ssh_populate"></a> [custom\_ssh\_populate](#input\_custom\_ssh\_populate)| any value excludes default ssh\_populate script used on container launch from userdata |`string`|`""`| no |
344
345
| <aname="input_custom_systemd"></a> [custom\_systemd](#input\_custom\_systemd)| any value excludes default systemd and hostname change from userdata |`string`|`""`| no |
345
346
| <aname="input_delete_network_interface_on_termination"></a> [delete\_network\_interface\_on\_termination](#input\_delete\_network\_interface\_on\_termination)| if network interface created for bastion host should be deleted when instance in terminated. Setting propagated to aws\_launch\_template.network\_interfaces.delete\_on\_termination |`bool`|`true`| no |
@@ -348,7 +349,7 @@ No modules.
348
349
| <aname="input_extra_user_data_content"></a> [extra\_user\_data\_content](#input\_extra\_user\_data\_content)| Extra user-data to add to the default built-in |`string`|`""`| no |
349
350
| <aname="input_extra_user_data_content_type"></a> [extra\_user\_data\_content\_type](#input\_extra\_user\_data\_content\_type)| What format is content in - eg 'text/cloud-config' or 'text/x-shellscript' |`string`|`"text/x-shellscript"`| no |
350
351
| <aname="input_extra_user_data_merge_type"></a> [extra\_user\_data\_merge\_type](#input\_extra\_user\_data\_merge\_type)| Control how cloud-init merges user-data sections |`string`|`"str(append)"`| no |
351
-
| <aname="input_lb_healthcheck_port"></a> [lb\_healthcheck\_port](#input\_lb\_healthcheck\_port)| TCP port to conduct lb target group healthchecks. Acceptable values are 22 or 2222|`string`|`"2222"`| no |
352
+
| <aname="input_lb_healthcheck_port"></a> [lb\_healthcheck\_port](#input\_lb\_healthcheck\_port)| TCP port to conduct lb target group healthchecks. Acceptable values are 2222 or the value defined for `bastion_service_port`|`string`|`"2222"`| no |
352
353
| <aname="input_lb_healthy_threshold"></a> [lb\_healthy\_threshold](#input\_lb\_healthy\_threshold)| Healthy threshold for lb target group |`string`|`"2"`| no |
353
354
| <aname="input_lb_interval"></a> [lb\_interval](#input\_lb\_interval)| interval for lb target group health check |`string`|`"30"`| no |
354
355
| <aname="input_lb_is_internal"></a> [lb\_is\_internal](#input\_lb\_is\_internal)| whether the lb will be internal |`string`|`false`| no |
Copy file name to clipboardExpand all lines: changelog.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,14 @@
1
+
# 8.1
2
+
3
+
-**Feature:** Make default permissive outbound security group rule creation conditional: `var.custom_outbound_security_group``type = bool`. Historic behaviour is followed by default
4
+
-**Feature:** Make bastion service port configurable: `var.bastion_service_port``type = number`. Historic behaviour is followed by default
5
+
-**Feature:** Add new `examples/custom_outbound_security_group` demonstrating use of above
6
+
-**Change:** Increment required terraform version to >= 1.2.0 since we are not testing historic versions
7
+
-**Change:** Increment suggested AWS provider to 4.22 (not hard enforce)
8
+
-**Change:** Remove obsolete explicit manual dependencies from examples
9
+
-**Change:** Remove obsolete quotes from interpolations in locals
10
+
-**Change:** Tidy up Readme to include new options sensibly
11
+
1
12
# 8.0
2
13
3
14
-**Change:** Defaults to Debian 11 (host) and Ubuntu 22.04 (Container). Alternative combinations, distributions and non-AMD64 platforms not tested at this time. Tested using
This example for more advanced use shows a complete setup for a new `bastion` service with all needed parts using a single AWS account similar to the sibling `examples/full-with-public-ip`.:
2
+
3
+
* a new VPC,
4
+
* private subnet(s) inside the VPC,
5
+
* an internet gateway and route tables.
6
+
7
+
**Additionally** a custom external security group is substituted for that normally created by the module all external IP ingress/egress, permitting only:
8
+
9
+
VPC egress ports:
10
+
11
+
- 53(UDP)
12
+
- 80(TCP)
13
+
- 443(TCP)
14
+
15
+
open for 0.0.0.0/0
16
+
17
+
VPC ingress:
18
+
19
+
- port 443(TCP)
20
+
21
+
open for 0.0.0.0/0
22
+
23
+
ssh is configured in the container to run on port 443 so connect with
| <aname="input_aws_region"></a> [aws\_region](#input\_aws\_region)| Default AWS region |`string`|`"eu-west-1"`| no |
69
+
| <aname="input_bastion_service_port"></a> [bastion\_service\_port](#input\_bastion\_service\_port)| Port for containerised ssh daemon |`number`|`443`| no |
70
+
| <aname="input_cidr-start"></a> [cidr-start](#input\_cidr-start)| Default CIDR block |`string`|`"10.50"`| no |
71
+
| <aname="input_custom_cidr"></a> [custom\_cidr](#input\_custom\_cidr)| CIDR for custom security gtoup ingress |`list(string)`| <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
72
+
| <aname="input_environment_name"></a> [environment\_name](#input\_environment\_name)| n/a |`string`|`"demo"`| no |
73
+
| <aname="input_everyone_cidr"></a> [everyone\_cidr](#input\_everyone\_cidr)| Everyone |`string`|`"0.0.0.0/0"`| no |
74
+
| <aname="input_tags"></a> [tags](#input\_tags)| tags aplied to all resources |`map(string)`|`{}`| no |
75
+
76
+
## Outputs
77
+
78
+
| Name | Description |
79
+
|------|-------------|
80
+
| <aname="output_bastion_service_role_name"></a> [bastion\_service\_role\_name](#output\_bastion\_service\_role\_name)| role created for service host asg - if created without assume role |
81
+
| <aname="output_bastion_sg_id_custom"></a> [bastion\_sg\_id\_custom](#output\_bastion\_sg\_id\_custom)| Custom (external) Security Group id of the bastion host |
82
+
| <aname="output_bastion_sg_id_module"></a> [bastion\_sg\_id\_module](#output\_bastion\_sg\_id\_module)| Sbuilt-in security Group id of the bastion host |
0 commit comments