From a777aad49fe2572a9f4e21c909cba61f193d465a Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Mon, 8 Aug 2022 15:39:49 +1000 Subject: [PATCH 1/8] Add ability to allow ssh commands only for specific users --- README.md | 175 ++++++++++++++++++++++++++------------------------- main.tf | 13 ++-- user_data.sh | 2 +- variables.tf | 6 ++ 4 files changed, 102 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index fa4a7e8..c881bd2 100644 --- a/README.md +++ b/README.md @@ -59,105 +59,106 @@ module "bastion" { ## Requirements -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | ~> 1.0 | -| [aws](#requirement\_aws) | ~> 4.0 | +| Name | Version | +| ------------------------------------------------------------------------- | ------- | +| [terraform](#requirement\_terraform) | ~> 1.0 | +| [aws](#requirement\_aws) | ~> 4.0 | ## Providers -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | ~> 4.0 | +| Name | Version | +| ------------------------------------------------- | ------- | +| [aws](#provider\_aws) | ~> 4.0 | ## Resources -| Name | Type | -|------|------| -| [aws_autoscaling_group.bastion_auto_scaling_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | -| [aws_iam_instance_profile.bastion_host_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | -| [aws_iam_policy.bastion_host_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | -| [aws_iam_role.bastion_host_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.bastion_host](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_kms_alias.alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | -| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_launch_template.bastion_launch_template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | -| [aws_lb.bastion_lb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | -| [aws_lb_listener.bastion_lb_listener_22](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | -| [aws_lb_target_group.bastion_lb_target_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | -| [aws_route53_record.bastion_record_name](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | -| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | -| [aws_s3_bucket_acl.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | -| [aws_s3_bucket_lifecycle_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | -| [aws_s3_bucket_server_side_encryption_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | -| [aws_s3_bucket_versioning.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | -| [aws_s3_object.bucket_public_keys_readme](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | -| [aws_security_group.bastion_host_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource || [aws_security_group.private_instances_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.egress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_instances](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource || [aws_ami.amazon-linux-2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | -| [aws_iam_policy_document.assume_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.bastion_host_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_kms_alias.kms-ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | -| [aws_subnet.subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| Name | Type | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | +| [aws_autoscaling_group.bastion_auto_scaling_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | +| [aws_iam_instance_profile.bastion_host_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_policy.bastion_host_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.bastion_host_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.bastion_host](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_kms_alias.alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_launch_template.bastion_launch_template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_lb.bastion_lb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | +| [aws_lb_listener.bastion_lb_listener_22](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | +| [aws_lb_target_group.bastion_lb_target_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_route53_record.bastion_record_name](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_acl.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | +| [aws_s3_bucket_lifecycle_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | +| [aws_s3_bucket_server_side_encryption_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_s3_bucket_versioning.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | +| [aws_s3_object.bucket_public_keys_readme](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | +| [aws_security_group.bastion_host_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | | [aws_security_group.private_instances_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.egress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_instances](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_ami.amazon-linux-2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_iam_policy_document.assume_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.bastion_host_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_kms_alias.kms-ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | +| [aws_subnet.subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | ## Inputs -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [allow\_ssh\_commands](#input\_allow\_ssh\_commands) | Allows the SSH user to execute one-off commands. Pass true to enable. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `bool` | `false` | no | -| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | n/a | `bool` | `true` | no | -| [auto\_scaling\_group\_subnets](#input\_auto\_scaling\_group\_subnets) | List of subnet were the Auto Scalling Group will deploy the instances | `list(string)` | n/a | yes | -| [bastion\_additional\_security\_groups](#input\_bastion\_additional\_security\_groups) | List of -additional security groups to attach to the launch template | `list(string)` | `[]` | no | -| [bastion\_ami](#input\_bastion\_ami) | The AMI that the Bastion Host will use. | `string` | `""` | no | -| [bastion\_host\_key\_pair](#input\_bastion\_host\_key\_pair) | Select the key pair to use to launch the bastion host | `any` | n/a | yes | -| [bastion\_iam\_permissions\_boundary](#input\_bastion\_iam\_permissions\_boundary) | IAM Role Permissions Boundary to constrain the bastion host role | `string` | `""` | no | -| [bastion\_iam\_policy\_name](#input\_bastion\_iam\_policy\_name) | IAM policy name to create for granting the instance role access to the bucket | `string` | `"BastionHost"` | no | -| [bastion\_iam\_role\_name](#input\_bastion\_iam\_role\_name) | IAM role name to create | `string` | `null` | no | -| [bastion\_instance\_count](#input\_bastion\_instance\_count) | n/a | `number` | `1` | no | -| [bastion\_launch\_template\_name](#input\_bastion\_launch\_template\_name) | Bastion Launch template Name, will also be used for the ASG | `string` | `"bastion-lt"` | no | -| [bastion\_record\_name](#input\_bastion\_record\_name) | DNS record name to use for the bastion | `string` | `""` | no | -| [bastion\_security\_group\_id](#input\_bastion\_security\_group\_id) | Custom security group to use | `string` | `""` | no | -| [bucket\_force\_destroy](#input\_bucket\_force\_destroy) | The bucket and all objects should be destroyed when -using true | `bool` | `false` | no | -| [bucket\_name](#input\_bucket\_name) | Bucket name were the bastion will store the logs | `any` | n/a | yes | -| [bucket\_versioning](#input\_bucket\_versioning) | Enable bucket versioning or not | `bool` | `true` | no | -| [cidrs](#input\_cidrs) | List of CIDRs than can access to the bastion. Default : 0.0.0.0/0 | `list(string)` |
[
"0.0.0.0/0"
]
| no | -| [create\_dns\_record](#input\_create\_dns\_record) | Choose if you want to create a record name for the bastion (LB). If true 'hosted\_zone\_id' and 'bastion\_record\_name' are mandatory | `any` | n/a | yes | -| [disk\_encrypt](#input\_disk\_encrypt) | Instance EBS encrypt | `bool` | `true` | no | -| [disk\_size](#input\_disk\_size) | Root EBS size in GB | `number` | `8` | no | -| [elb\_subnets](#input\_elb\_subnets) | List of subnet were the ELB will be deployed | `list(string)` | n/a | yes | -| [enable\_logs\_s3\_sync](#input\_enable\_logs\_s3\_sync) | Enable cron job to copy logs to S3 | `bool` | `true` -| no | -| [extra\_user\_data\_content](#input\_extra\_user\_data\_content) | Additional scripting to pass to the bastion host. For example, this can include installing postgresql for the `psql` command. | `string` | `""` | no | -| [hosted\_zone\_id](#input\_hosted\_zone\_id) | Name of the hosted zone were we'll register the bastion DNS name | `string` | `""` | no | -| [instance\_type](#input\_instance\_type) | Instance size of the bastion | `string` | `"t3.nano"` | no | -| [ipv6\_cidrs](#input\_ipv6\_cidrs) | List of IPv6 CIDRs than can access to the bastion. Default : ::/0 | `list(string)` |
[
"::/0"
]
| no | -| [is\_lb\_private](#input\_is\_lb\_private) | If TRUE the load balancer scheme will be "internal" else "internet-facing" | `any` | n/a | yes | -| [kms\_enable\_key\_rotation](#input\_kms\_enable\_key\_rotation) | Enable key rotation for the KMS key | `bool` | `false` | no | -| [log\_auto\_clean](#input\_log\_auto\_clean) | Enable or not the lifecycle | `bool` | `false` | no | -| [log\_expiry\_days](#input\_log\_expiry\_days) | Number of days before logs expiration | `number` | `90` | no | -| [log\_glacier\_days](#input\_log\_glacier\_days) | Number of days before moving logs to Glacier | `number` | `60` | no | -| [log\_standard\_ia\_days](#input\_log\_standard\_ia\_days) | Number of days before moving logs to IA Storage | -`number` | `30` | no | -| [private\_ssh\_port](#input\_private\_ssh\_port) | Set the SSH port to use between the bastion and private instance | `number` | `22` | no | -| [public\_ssh\_port](#input\_public\_ssh\_port) | Set the SSH port to use from desktop to the bastion | `number` | `22` | no | -| [region](#input\_region) | n/a | `any` | n/a | yes | -| [tags](#input\_tags) | A mapping of tags to assign | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | VPC id were we'll deploy the bastion | `any` | n/a | yes | +| Name | Description | Type | Default | Required | +| ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------- | :------: | +| [allow\_ssh\_commands](#input\_allow\_ssh\_commands) | Allows the SSH user to execute one-off commands. Pass true to enable. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `bool` | `false` | no | +| [allow\_ssh\_commands\_for\)users](#input\_allow\_ssh\_commands\_for\_users) | Allows a list of users to execute one-off commands. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `list(string)` | `[]` | no | +| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | n/a | `bool` | `true` | no | +| [auto\_scaling\_group\_subnets](#input\_auto\_scaling\_group\_subnets) | List of subnet were the Auto Scalling Group will deploy the instances | `list(string)` | n/a | yes | +| [bastion\_additional\_security\_groups](#input\_bastion\_additional\_security\_groups) | List of | +| additional security groups to attach to the launch template | `list(string)` | `[]` | no | +| [bastion\_ami](#input\_bastion\_ami) | The AMI that the Bastion Host will use. | `string` | `""` | no | +| [bastion\_host\_key\_pair](#input\_bastion\_host\_key\_pair) | Select the key pair to use to launch the bastion host | `any` | n/a | yes | +| [bastion\_iam\_permissions\_boundary](#input\_bastion\_iam\_permissions\_boundary) | IAM Role Permissions Boundary to constrain the bastion host role | `string` | `""` | no | +| [bastion\_iam\_policy\_name](#input\_bastion\_iam\_policy\_name) | IAM policy name to create for granting the instance role access to the bucket | `string` | `"BastionHost"` | no | +| [bastion\_iam\_role\_name](#input\_bastion\_iam\_role\_name) | IAM role name to create | `string` | `null` | no | +| [bastion\_instance\_count](#input\_bastion\_instance\_count) | n/a | `number` | `1` | no | +| [bastion\_launch\_template\_name](#input\_bastion\_launch\_template\_name) | Bastion Launch template Name, will also be used for the ASG | `string` | `"bastion-lt"` | no | +| [bastion\_record\_name](#input\_bastion\_record\_name) | DNS record name to use for the bastion | `string` | `""` | no | +| [bastion\_security\_group\_id](#input\_bastion\_security\_group\_id) | Custom security group to use | `string` | `""` | no | +| [bucket\_force\_destroy](#input\_bucket\_force\_destroy) | The bucket and all objects should be destroyed when | +| using true | `bool` | `false` | no | +| [bucket\_name](#input\_bucket\_name) | Bucket name were the bastion will store the logs | `any` | n/a | yes | +| [bucket\_versioning](#input\_bucket\_versioning) | Enable bucket versioning or not | `bool` | `true` | no | +| [cidrs](#input\_cidrs) | List of CIDRs than can access to the bastion. Default : 0.0.0.0/0 | `list(string)` |
[
"0.0.0.0/0"
]
| no | +| [create\_dns\_record](#input\_create\_dns\_record) | Choose if you want to create a record name for the bastion (LB). If true 'hosted\_zone\_id' and 'bastion\_record\_name' are mandatory | `any` | n/a | yes | +| [disk\_encrypt](#input\_disk\_encrypt) | Instance EBS encrypt | `bool` | `true` | no | +| [disk\_size](#input\_disk\_size) | Root EBS size in GB | `number` | `8` | no | +| [elb\_subnets](#input\_elb\_subnets) | List of subnet were the ELB will be deployed | `list(string)` | n/a | yes | +| [enable\_logs\_s3\_sync](#input\_enable\_logs\_s3\_sync) | Enable cron job to copy logs to S3 | `bool` | `true` | +| no | +| [extra\_user\_data\_content](#input\_extra\_user\_data\_content) | Additional scripting to pass to the bastion host. For example, this can include installing postgresql for the `psql` command. | `string` | `""` | no | +| [hosted\_zone\_id](#input\_hosted\_zone\_id) | Name of the hosted zone were we'll register the bastion DNS name | `string` | `""` | no | +| [instance\_type](#input\_instance\_type) | Instance size of the bastion | `string` | `"t3.nano"` | no | +| [ipv6\_cidrs](#input\_ipv6\_cidrs) | List of IPv6 CIDRs than can access to the bastion. Default : ::/0 | `list(string)` |
[
"::/0"
]
| no | +| [is\_lb\_private](#input\_is\_lb\_private) | If TRUE the load balancer scheme will be "internal" else "internet-facing" | `any` | n/a | yes | +| [kms\_enable\_key\_rotation](#input\_kms\_enable\_key\_rotation) | Enable key rotation for the KMS key | `bool` | `false` | no | +| [log\_auto\_clean](#input\_log\_auto\_clean) | Enable or not the lifecycle | `bool` | `false` | no | +| [log\_expiry\_days](#input\_log\_expiry\_days) | Number of days before logs expiration | `number` | `90` | no | +| [log\_glacier\_days](#input\_log\_glacier\_days) | Number of days before moving logs to Glacier | `number` | `60` | no | +| [log\_standard\_ia\_days](#input\_log\_standard\_ia\_days) | Number of days before moving logs to IA Storage | +| `number` | `30` | no | +| [private\_ssh\_port](#input\_private\_ssh\_port) | Set the SSH port to use between the bastion and private instance | `number` | `22` | no | +| [public\_ssh\_port](#input\_public\_ssh\_port) | Set the SSH port to use from desktop to the bastion | `number` | `22` | no | +| [region](#input\_region) | n/a | `any` | n/a | yes | +| [tags](#input\_tags) | A mapping of tags to assign | `map(string)` | `{}` | no | +| [vpc\_id](#input\_vpc\_id) | VPC id were we'll deploy the bastion | `any` | n/a | yes | ## Outputs -| Name | Description | -|------|-------------| -| [bastion\_auto\_scaling\_group\_name](#output\_bastion\_auto\_scaling\_group\_name) | n/a | -| [bastion\_host\_security\_group](#output\_bastion\_host\_security\_group) | n/a | -| [bucket\_kms\_key\_alias](#output\_bucket\_kms\_key\_alias) | n/a | -| [bucket\_kms\_key\_arn](#output\_bucket\_kms\_key\_arn) | n/a | -| [bucket\_name](#output\_bucket\_name) | n/a | -| [elb\_ip](#output\_elb\_ip) | n/a | -| [private\_instances\_security\_group](#output\_private\_instances\_security\_group) | n/a | +| Name | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| [bastion\_auto\_scaling\_group\_name](#output\_bastion\_auto\_scaling\_group\_name) | n/a | +| [bastion\_host\_security\_group](#output\_bastion\_host\_security\_group) | n/a | +| [bucket\_kms\_key\_alias](#output\_bucket\_kms\_key\_alias) | n/a | +| [bucket\_kms\_key\_arn](#output\_bucket\_kms\_key\_arn) | n/a | +| [bucket\_name](#output\_bucket\_name) | n/a | +| [elb\_ip](#output\_elb\_ip) | n/a | +| [private\_instances\_security\_group](#output\_private\_instances\_security\_group) | n/a | Known issues ------------ diff --git a/main.tf b/main.tf index 1c79135..2fb8bae 100644 --- a/main.tf +++ b/main.tf @@ -217,12 +217,13 @@ resource "aws_launch_template" "bastion_launch_template" { key_name = var.bastion_host_key_pair user_data = base64encode(templatefile("${path.module}/user_data.sh", { - aws_region = var.region - bucket_name = var.bucket_name - extra_user_data_content = var.extra_user_data_content - allow_ssh_commands = lower(var.allow_ssh_commands) - public_ssh_port = var.public_ssh_port - sync_logs_cron_job = var.enable_logs_s3_sync ? "*/5 * * * * /usr/bin/bastion/sync_s3" : "" + aws_region = var.region + bucket_name = var.bucket_name + extra_user_data_content = var.extra_user_data_content + allow_ssh_commands = lower(var.allow_ssh_commands) + allow_ssh_commands_for_users = var.allow_ssh_commands_for_users + public_ssh_port = var.public_ssh_port + sync_logs_cron_job = var.enable_logs_s3_sync ? "*/5 * * * * /usr/bin/bastion/sync_s3" : "" })) block_device_mappings { diff --git a/user_data.sh b/user_data.sh index a6f397e..7fadfe0 100644 --- a/user_data.sh +++ b/user_data.sh @@ -49,7 +49,7 @@ if [[ -z $SSH_ORIGINAL_COMMAND ]]; then else # If the module consumer wants to allow remote commands (for ansible or other) then allow that command through. - if [ "${allow_ssh_commands}" == "true" ]; then + if [ "${allow_ssh_commands}" == "true" ]%{ for user in allow_ssh_commands_for_users } || [ "${user}" == "`whoami`" ]%{endfor ~}; then exec /bin/bash -c "$SSH_ORIGINAL_COMMAND" else # The "script" program could be circumvented with some commands (e.g. bash, nc). diff --git a/variables.tf b/variables.tf index f850ffa..75480c7 100644 --- a/variables.tf +++ b/variables.tf @@ -138,6 +138,12 @@ variable "allow_ssh_commands" { default = false } +variable "allow_ssh_commands_for_users" { + description = "Allows a list of users to execute one-off commands. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion." + type = list(string) + default = [] +} + variable "bastion_iam_role_name" { description = "IAM role name to create" type = string From 39ccede0fd9aae8f86a92651fa70de0afafd1991 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 9 Aug 2022 17:38:05 +1000 Subject: [PATCH 2/8] Support instance refresh --- main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.tf b/main.tf index 2fb8bae..d6023cd 100644 --- a/main.tf +++ b/main.tf @@ -292,6 +292,10 @@ resource "aws_autoscaling_group" "bastion_auto_scaling_group" { propagate_at_launch = true } + instance_refresh { + strategy = "Rolling" + } + lifecycle { create_before_destroy = true } From d76bfb15b035cac1030173570000931c00a6c481 Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 9 Aug 2022 17:48:33 +1000 Subject: [PATCH 3/8] Trigger instance refresh on launch template version updates --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index d6023cd..7727ad1 100644 --- a/main.tf +++ b/main.tf @@ -256,7 +256,7 @@ resource "aws_autoscaling_group" "bastion_auto_scaling_group" { name_prefix = "ASG-${local.name_prefix}" launch_template { id = aws_launch_template.bastion_launch_template.id - version = "$Latest" + version = aws_launch_template.bastion_launch_template.latest_version } max_size = var.bastion_instance_count min_size = var.bastion_instance_count From 63565b9430ae66c8b6630071754bbacb1dc9dff9 Mon Sep 17 00:00:00 2001 From: Tony Cosentini Date: Mon, 5 Dec 2022 10:45:29 +0800 Subject: [PATCH 4/8] Disable metadata endpoints on bastion instances. --- main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.tf b/main.tf index 7727ad1..b134c49 100644 --- a/main.tf +++ b/main.tf @@ -247,6 +247,10 @@ resource "aws_launch_template" "bastion_launch_template" { tags = merge(tomap({ "Name" = var.bastion_launch_template_name }), merge(var.tags)) } + metadata_options { + http_endpoint = "disabled" + } + lifecycle { create_before_destroy = true } From 30a125644f7e786482f429c24eda54a42487cb86 Mon Sep 17 00:00:00 2001 From: Tony Cosentini Date: Tue, 6 Dec 2022 16:22:04 +0800 Subject: [PATCH 5/8] Allow metadata endpoint with session tokens. --- main.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index b134c49..91d3519 100644 --- a/main.tf +++ b/main.tf @@ -248,7 +248,8 @@ resource "aws_launch_template" "bastion_launch_template" { } metadata_options { - http_endpoint = "disabled" + http_endpoint = "enabled" + http_tokens = "required" } lifecycle { From 742418f96e4245dea4003e7f5d7cfdff41637995 Mon Sep 17 00:00:00 2001 From: Mario de Frutos Date: Thu, 15 Jun 2023 17:11:01 +0200 Subject: [PATCH 6/8] Allow AWS provider v5 Signed-off-by: Mario de Frutos --- providers.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers.tf b/providers.tf index bad6faa..7800deb 100644 --- a/providers.tf +++ b/providers.tf @@ -2,7 +2,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 4.0" + version = ">= 4.0" } } From dbdfb87b3beba44dd9c1ad6b487261245006fe2c Mon Sep 17 00:00:00 2001 From: Mario de Frutos Date: Thu, 15 Jun 2023 18:09:08 +0200 Subject: [PATCH 7/8] Set ACL private explicitely due to changes in version 5 In Terraform AWS provider vestion 5 the acl option in the aws_s3_object doesn't have default value set to private so we need to add it explicitly Signed-off-by: Mario de Frutos --- main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/main.tf b/main.tf index 91d3519..a1ac3d3 100644 --- a/main.tf +++ b/main.tf @@ -13,6 +13,7 @@ data "aws_kms_alias" "kms-ebs" { } resource "aws_s3_object" "bucket_public_keys_readme" { + acl = "private" bucket = aws_s3_bucket.bucket.id key = "public-keys/README.txt" content = "Drop here the ssh public keys of the instances you want to control" From 2c78731ca841cf8c44414f6644725f8599e716fb Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 25 Jul 2023 13:42:10 +1000 Subject: [PATCH 8/8] Fix README.md --- README.md | 186 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 98 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index 97e1f5b..8895d70 100644 --- a/README.md +++ b/README.md @@ -60,16 +60,16 @@ module "bastion" { ## Requirements -| Name | Version | -| ------------------------------------------------------------------------- | ------- | -| [terraform](#requirement\_terraform) | ~> 1.0 | -| [aws](#requirement\_aws) | ~> 4.0 | +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.0 | +| [aws](#requirement\_aws) | ~> 4.0 | ## Providers -| Name | Version | -| ------------------------------------------------- | ------- | -| [aws](#provider\_aws) | ~> 4.0 | +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 4.0 | ## Modules @@ -77,93 +77,103 @@ No modules. ## Resources -| Name | Type | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| [aws_autoscaling_group.bastion_auto_scaling_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | -| [aws_iam_instance_profile.bastion_host_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | -| [aws_iam_policy.bastion_host_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | -| [aws_iam_role.bastion_host_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.bastion_host](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_kms_alias.alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | -| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_launch_template.bastion_launch_template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | -| [aws_lb.bastion_lb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | -| [aws_lb_listener.bastion_lb_listener_22](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | -| [aws_lb_target_group.bastion_lb_target_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | -| [aws_route53_record.bastion_record_name](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | -| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | -| [aws_s3_bucket_acl.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | -| [aws_s3_bucket_lifecycle_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | -| [aws_s3_bucket_server_side_encryption_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | -| [aws_s3_bucket_versioning.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | -| [aws_s3_object.bucket_public_keys_readme](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | -| [aws_security_group.bastion_host_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | | [aws_security_group.private_instances_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.egress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_instances](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_ami.amazon-linux-2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | -| [aws_iam_policy_document.assume_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.bastion_host_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_kms_alias.kms-ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | -| [aws_subnet.subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | +| Name | Type | +|------|------| +| [aws_autoscaling_group.bastion_auto_scaling_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource | +| [aws_iam_instance_profile.bastion_host_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_policy.bastion_host_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.bastion_host_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy_attachment.bastion_host](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_kms_alias.alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_launch_template.bastion_launch_template](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_lb.bastion_lb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | +| [aws_lb_listener.bastion_lb_listener_22](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | +| [aws_lb_target_group.bastion_lb_target_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_route53_record.bastion_record_name](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | +| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_acl.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | +| [aws_s3_bucket_lifecycle_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | +| [aws_s3_bucket_ownership_controls.bucket-acl-ownership](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | +| [aws_s3_bucket_server_side_encryption_configuration.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_s3_bucket_versioning.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | +| [aws_s3_object.bucket_public_keys_readme](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | +| [aws_security_group.bastion_host_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group.private_instances_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group_rule.egress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_bastion](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_security_group_rule.ingress_instances](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | +| [aws_ami.amazon-linux-2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_iam_policy_document.assume_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.bastion_host_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_kms_alias.kms-ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_alias) | data source | +| [aws_subnet.subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | ## Inputs -| Name | Description | Type | Default | Required | -| ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------- | :------: | -| [allow\_ssh\_commands](#input\_allow\_ssh\_commands) | Allows the SSH user to execute one-off commands. Pass true to enable. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `bool` | `false` | no | -| [allow\_ssh\_commands\_for\)users](#input\_allow\_ssh\_commands\_for\_users) | Allows a list of users to execute one-off commands. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `list(string)` | `[]` | no | -| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | n/a | `bool` | `true` | no | -| [auto\_scaling\_group\_subnets](#input\_auto\_scaling\_group\_subnets) | List of subnet were the Auto Scalling Group will deploy the instances | `list(string)` | n/a | yes | -| [bastion\_additional\_security\_groups](#input\_bastion\_additional\_security\_groups) | List of | -| additional security groups to attach to the launch template | `list(string)` | `[]` | no | -| [bastion\_ami](#input\_bastion\_ami) | The AMI that the Bastion Host will use. | `string` | `""` | no | -| [bastion\_host\_key\_pair](#input\_bastion\_host\_key\_pair) | Select the key pair to use to launch the bastion host | `any` | n/a | yes | -| [bastion\_iam\_permissions\_boundary](#input\_bastion\_iam\_permissions\_boundary) | IAM Role Permissions Boundary to constrain the bastion host role | `string` | `""` | no | -| [bastion\_iam\_policy\_name](#input\_bastion\_iam\_policy\_name) | IAM policy name to create for granting the instance role access to the bucket | `string` | `"BastionHost"` | no | -| [bastion\_iam\_role\_name](#input\_bastion\_iam\_role\_name) | IAM role name to create | `string` | `null` | no | -| [bastion\_instance\_count](#input\_bastion\_instance\_count) | n/a | `number` | `1` | no | -| [bastion\_launch\_template\_name](#input\_bastion\_launch\_template\_name) | Bastion Launch template Name, will also be used for the ASG | `string` | `"bastion-lt"` | no | -| [bastion\_record\_name](#input\_bastion\_record\_name) | DNS record name to use for the bastion | `string` | `""` | no | -| [bastion\_security\_group\_id](#input\_bastion\_security\_group\_id) | Custom security group to use | `string` | `""` | no | -| [bucket\_force\_destroy](#input\_bucket\_force\_destroy) | The bucket and all objects should be destroyed when | -| using true | `bool` | `false` | no | -| [bucket\_name](#input\_bucket\_name) | Bucket name were the bastion will store the logs | `any` | n/a | yes | -| [bucket\_versioning](#input\_bucket\_versioning) | Enable bucket versioning or not | `bool` | `true` | no | -| [cidrs](#input\_cidrs) | List of CIDRs than can access to the bastion. Default : 0.0.0.0/0 | `list(string)` |
[
"0.0.0.0/0"
]
| no | -| [create\_dns\_record](#input\_create\_dns\_record) | Choose if you want to create a record name for the bastion (LB). If true 'hosted\_zone\_id' and 'bastion\_record\_name' are mandatory | `any` | n/a | yes | -| [disk\_encrypt](#input\_disk\_encrypt) | Instance EBS encrypt | `bool` | `true` | no | -| [disk\_size](#input\_disk\_size) | Root EBS size in GB | `number` | `8` | no | -| [elb\_subnets](#input\_elb\_subnets) | List of subnet were the ELB will be deployed | `list(string)` | n/a | yes | -| [enable\_logs\_s3\_sync](#input\_enable\_logs\_s3\_sync) | Enable cron job to copy logs to S3 | `bool` | `true` | -| no | -| [extra\_user\_data\_content](#input\_extra\_user\_data\_content) | Additional scripting to pass to the bastion host. For example, this can include installing postgresql for the `psql` command. | `string` | `""` | no | -| [hosted\_zone\_id](#input\_hosted\_zone\_id) | Name of the hosted zone were we'll register the bastion DNS name | `string` | `""` | no | -| [instance\_type](#input\_instance\_type) | Instance size of the bastion | `string` | `"t3.nano"` | no | -| [ipv6\_cidrs](#input\_ipv6\_cidrs) | List of IPv6 CIDRs than can access to the bastion. Default : ::/0 | `list(string)` |
[
"::/0"
]
| no | -| [is\_lb\_private](#input\_is\_lb\_private) | If TRUE the load balancer scheme will be "internal" else "internet-facing" | `any` | n/a | yes | -| [kms\_enable\_key\_rotation](#input\_kms\_enable\_key\_rotation) | Enable key rotation for the KMS key | `bool` | `false` | no | -| [log\_auto\_clean](#input\_log\_auto\_clean) | Enable or not the lifecycle | `bool` | `false` | no | -| [log\_expiry\_days](#input\_log\_expiry\_days) | Number of days before logs expiration | `number` | `90` | no | -| [log\_glacier\_days](#input\_log\_glacier\_days) | Number of days before moving logs to Glacier | `number` | `60` | no | -| [log\_standard\_ia\_days](#input\_log\_standard\_ia\_days) | Number of days before moving logs to IA Storage | -| `number` | `30` | no | -| [private\_ssh\_port](#input\_private\_ssh\_port) | Set the SSH port to use between the bastion and private instance | `number` | `22` | no | -| [public\_ssh\_port](#input\_public\_ssh\_port) | Set the SSH port to use from desktop to the bastion | `number` | `22` | no | -| [region](#input\_region) | n/a | `any` | n/a | yes | -| [tags](#input\_tags) | A mapping of tags to assign | `map(string)` | `{}` | no | -| [vpc\_id](#input\_vpc\_id) | VPC id were we'll deploy the bastion | `any` | n/a | yes | +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [allow\_ssh\_commands](#input\_allow\_ssh\_commands) | Allows the SSH user to execute one-off commands. Pass true to enable. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `bool` | `false` | no | +| [allow\_ssh\_commands\_for\)users](#input\_allow\_ssh\_commands\_for\_users) | Allows a list of users to execute one-off commands. Warning: These commands are not logged and increase the vulnerability of the system. Use at your own discretion. | `list(string)` | `[]` | no | +| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | n/a | `bool` | `true` | no | +| [auto\_scaling\_group\_subnets](#input\_auto\_scaling\_group\_subnets) | List of subnets where the Auto Scaling Group will deploy the instances | `list(string)` | n/a | yes | +| [bastion\_additional\_security\_groups](#input\_bastion\_additional\_security\_groups) | List of additional security groups to attach to the launch template | `list(string)` | `[]` | no | +| [bastion\_ami](#input\_bastion\_ami) | The AMI that the Bastion Host will use. | `string` | `""` | no | +| [bastion\_host\_key\_pair](#input\_bastion\_host\_key\_pair) | Select the key pair to use to launch the bastion host | `string` | n/a | yes | +| [bastion\_iam\_permissions\_boundary](#input\_bastion\_iam\_permissions\_boundary) | IAM Role Permissions Boundary to constrain the bastion host role | `string` | `""` | no | +| [bastion\_iam\_policy\_name](#input\_bastion\_iam\_policy\_name) | IAM policy name to create for granting the instance role access to the bucket | `string` | `"BastionHost"` | no | +| [bastion\_iam\_role\_name](#input\_bastion\_iam\_role\_name) | IAM role name to create | `string` | `null` | no | +| [bastion\_instance\_count](#input\_bastion\_instance\_count) | n/a | `number` | `1` | no | +| [bastion\_launch\_template\_name](#input\_bastion\_launch\_template\_name) | Bastion Launch template Name, will also be used for the ASG | `string` | `"bastion-lt"` | no | +| [bastion\_record\_name](#input\_bastion\_record\_name) | DNS record name to use for the bastion | `string` | `""` | no | +| [bastion\_security\_group\_id](#input\_bastion\_security\_group\_id) | Custom security group to use | `string` | `""` | no | +| [bucket\_force\_destroy](#input\_bucket\_force\_destroy) | The bucket and all objects should be destroyed when using true | `bool` | `false` | no | +| [bucket\_name](#input\_bucket\_name) | Bucket name where the bastion will store the logs | `string` | n/a | yes | +| [bucket\_versioning](#input\_bucket\_versioning) | Enable bucket versioning or not | `bool` | `true` | no | +| [cidrs](#input\_cidrs) | List of CIDRs that can access the bastion. Default: 0.0.0.0/0 | `list(string)` |
[
"0.0.0.0/0"
]
| no | +| [create\_dns\_record](#input\_create\_dns\_record) | Choose if you want to create a record name for the bastion (LB). If true, 'hosted\_zone\_id' and 'bastion\_record\_name' are mandatory | `bool` | n/a | yes | +| [create\_elb](#input\_create\_elb) | Choose if you want to deploy an ELB for accessing bastion hosts. Only select false if there is no need to SSH into bastion from outside. If true, you must set elb\_subnets and is\_lb\_private | `bool` | `true` | no | +| [disk\_encrypt](#input\_disk\_encrypt) | Instance EBS encryption | `bool` | `true` | no | +| [disk\_size](#input\_disk\_size) | Root EBS size in GB | `number` | `8` | no | +| [elb\_subnets](#input\_elb\_subnets) | List of subnets where the ELB will be deployed | `list(string)` | `[]` | no | +| [enable\_http\_protocol\_ipv6](#input\_enable\_http\_protocol\_ipv6) | Enables or disables the IPv6 endpoint for the instance metadata service | `bool` | `false` | no | +| [enable\_instance\_metadata\_tags](#input\_enable\_instance\_metadata\_tags) | Enables or disables access to instance tags from the instance metadata service | `bool` | `false` | no | +| [enable\_logs\_s3\_sync](#input\_enable\_logs\_s3\_sync) | Enable cron job to copy logs to S3 | `bool` | `true` | no | +| [extra\_user\_data\_content](#input\_extra\_user\_data\_content) | Additional scripting to pass to the bastion host. For example, this can include installing PostgreSQL for the `psql` command. | `string` | `""` | no | +| [hosted\_zone\_id](#input\_hosted\_zone\_id) | Name of the hosted zone where we'll register the bastion DNS name | `string` | `""` | no | +| [http\_endpoint](#input\_http\_endpoint) | Whether the metadata service is available | `bool` | `true` | no | +| [http\_put\_response\_hop\_limit](#input\_http\_put\_response\_hop\_limit) | The desired HTTP PUT response hop limit for instance metadata requests | `number` | `1` | no | +| [instance\_type](#input\_instance\_type) | Instance size of the bastion | `string` | `"t3.nano"` | no | +| [ipv6\_cidrs](#input\_ipv6\_cidrs) | List of IPv6 CIDRs that can access the bastion. Default: ::/0 | `list(string)` |
[
"::/0"
]
| no | +| [is\_lb\_private](#input\_is\_lb\_private) | If TRUE, the load balancer scheme will be "internal" else "internet-facing" | `bool` | `null` | no | +| [kms\_enable\_key\_rotation](#input\_kms\_enable\_key\_rotation) | Enable key rotation for the KMS key | `bool` | `false` | no | +| [log\_auto\_clean](#input\_log\_auto\_clean) | Enable or disable the lifecycle | `bool` | `false` | no | +| [log\_expiry\_days](#input\_log\_expiry\_days) | Number of days before logs expiration | `number` | `90` | no | +| [log\_glacier\_days](#input\_log\_glacier\_days) | Number of days before moving logs to Glacier | `number` | `60` | no | +| [log\_standard\_ia\_days](#input\_log\_standard\_ia\_days) | Number of days before moving logs to IA Storage | `number` | `30` | no | +| [private\_ssh\_port](#input\_private\_ssh\_port) | Set the SSH port to use between the bastion and private instance | `number` | `22` | no | +| [public\_ssh\_port](#input\_public\_ssh\_port) | Set the SSH port to use from desktop to the bastion | `number` | `22` | no | +| [region](#input\_region) | n/a | `string` | n/a | yes | +| [tags](#input\_tags) | A mapping of tags to assign | `map(string)` | `{}` | no | +| [use\_imds\_v2](#input\_use\_imds\_v2) | Use (IMDSv2) Instance Metadata Service V2 | `bool` | `false` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID where we'll deploy the bastion | `string` | n/a | yes | ## Outputs -| Name | Description | -| ------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | -| [bastion\_auto\_scaling\_group\_name](#output\_bastion\_auto\_scaling\_group\_name) | n/a | -| [bastion\_host\_security\_group](#output\_bastion\_host\_security\_group) | n/a | -| [bucket\_kms\_key\_alias](#output\_bucket\_kms\_key\_alias) | n/a | -| [bucket\_kms\_key\_arn](#output\_bucket\_kms\_key\_arn) | n/a | -| [bucket\_name](#output\_bucket\_name) | n/a | -| [elb\_ip](#output\_elb\_ip) | n/a | -| [private\_instances\_security\_group](#output\_private\_instances\_security\_group) | n/a | +| Name | Description | +|------|-------------| +| [bastion\_auto\_scaling\_group\_name](#output\_bastion\_auto\_scaling\_group\_name) | The name of the Auto Scaling Group for bastion hosts | +| [bastion\_elb\_id](#output\_bastion\_elb\_id) | The ID of the ELB for bastion hosts | +| [bastion\_host\_security\_group](#output\_bastion\_host\_security\_group) | The ID of the bastion host security group | +| [bucket\_arn](#output\_bucket\_arn) | The ARN of the S3 bucket | +| [bucket\_kms\_key\_alias](#output\_bucket\_kms\_key\_alias) | The name of the KMS key alias for the bucket | +| [bucket\_kms\_key\_arn](#output\_bucket\_kms\_key\_arn) | The ARN of the KMS key for the bucket | +| [bucket\_name](#output\_bucket\_name) | The ID of the S3 bucket | +| [elb\_arn](#output\_elb\_arn) | The ARN of the ELB for bastion hosts | +| [elb\_ip](#output\_elb\_ip) | The DNS name of the ELB for bastion hosts | +| [private\_instances\_security\_group](#output\_private\_instances\_security\_group) | The ID of the security group for private instances | +| [target\_group\_arn](#output\_target\_group\_arn) | The ARN of the target group for the ELB | + Known issues ------------