Skip to content

Commit

Permalink
chore: Update Terraform versions and required providers in modules
Browse files Browse the repository at this point in the history
  • Loading branch information
ulises-jeremias committed Aug 5, 2024
1 parent 9ce6c26 commit aedb3d4
Show file tree
Hide file tree
Showing 35 changed files with 1,376 additions and 532 deletions.
2 changes: 1 addition & 1 deletion live/common-infra/configs/prod.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ region = "us-west-2"
name = "common-infra"
namespace = "nan"
environment = "prod"
tags = {}
tags = {}

# Core Networking settings

Expand Down
2 changes: 1 addition & 1 deletion live/common-infra/configs/staging.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ region = "us-west-2"
name = "common-infra"
namespace = "nan"
environment = "staging"
tags = {}
tags = {}

# Core Networking settings

Expand Down
2 changes: 1 addition & 1 deletion live/core-networking/configs/prod.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ region = "us-west-2"
name = "core-networking"
namespace = "nan"
environment = "prod"
tags = {}
tags = {}

# AWS settings

Expand Down
2 changes: 1 addition & 1 deletion live/core-networking/configs/staging.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ region = "us-west-2"
name = "core-networking"
namespace = "nan"
environment = "staging"
tags = {}
tags = {}

# AWS settings

Expand Down
2 changes: 1 addition & 1 deletion live/terraform-backend/configs/prod.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ region = "us-west-2"
name = "tf-backend"
namespace = "nan"
environment = "prod"
tags = {}
tags = {}
2 changes: 1 addition & 1 deletion live/terraform-backend/configs/staging.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ region = "us-west-2"
name = "tf-backend"
namespace = "nan"
environment = "staging"
tags = {}
tags = {}
File renamed without changes.
35 changes: 35 additions & 0 deletions modules/bastion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,41 @@ ssh -i /path/to/your/private/key ubuntu@$bastion_instance_id

### Optional Steps

The following steps are optional and can be used to further secure the Bastion host
or to streamline the connection process.

#### Quick Connection Using Script

To streamline the process of connecting to the Bastion host, you can use the provided `connect.sh` script. This script automates the steps of generating an SSH key, uploading it to the instance, and establishing a connection through AWS Systems Manager.

```sh
./scripts/connect.sh -i <instance-id>
```

Replace `<instance-id>` with the ID of the Bastion host instance. The script will generate an SSH key pair, upload the public key to the Bastion host, and establish an SSH connection using the private key.

Use the `-h` or `--help` flag to see the available options:

```sh
$ ./scripts/connect.sh --help

Script to connect to an AWS Bastion host. Usage:

connect.sh [option] ARGUMENTS...

Options:
-h, --help Display this help message

--instance-id=INSTANCE_ID EC2 instance ID of the Bastion host
--tag=TAG Tag to identify the Bastion host.
Will be used to retrieve the instance ID.
If not provided, instance ID must be provided.
Will be ignored if instance ID is provided.

--key-name=KEY_NAME Name of the SSH key file (default: bastion_key)
--key-dir=KEY_DIR Directory to store the SSH key (default: ~/.ssh)
```
#### Use Other SSH Options to Open Connection
It is possible to use different options to open connection to bastion host. For example you can use -D 8888 option to open SSH connection with a local “dynamic” application-level port forwarding through 8888 port. See [this link](https://explainshell.com/explain?cmd=ssh+-i+%24PRIVATE_KEY_FILE+-D+8888+ubuntu%40%24INSTANCE_ID) for detailed explanation.
Expand Down
11 changes: 11 additions & 0 deletions modules/bastion/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ resource "aws_iam_role_policy" "bastion_host_iam_role" {
"secretsmanager:GetSecretValue"
],
"Resource" : "arn:aws:secretsmanager:*:*:secret:*"
},
{
"Effect" : "Allow",
"Action" : [
"eks:ListClusters",
"eks:DescribeCluster",
"eks:ListNodegroups",
"eks:DescribeNodegroup",
"eks:AccessKubernetesApi"
],
"Resource" : "*"
}
]
})
Expand Down
106 changes: 106 additions & 0 deletions modules/bastion/scripts/connect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bash

##
## Script to connect to an AWS Bastion host or create a tunnel through the bastion host. Usage:
##
## @script.name [option] ARGUMENTS...
##
## Options:
## -h, --help Display this help message
##
## --instance-id=INSTANCE_ID EC2 instance ID of the Bastion host
## --tag=TAG Tag to identify the Bastion host.
## Will be used to retrieve the instance ID.
## If not provided, instance ID must be provided.
## Will be ignored if instance ID is provided.
##
## --key-name=KEY_NAME Name of the SSH key file (default: bastion_key)
## --key-dir=KEY_DIR Directory to store the SSH key (default: ~/.ssh)
##
## --bastion-user=USER Username for the bastion host (default: ubuntu)
## --tunnel=LOCAL_PORT:REMOTE_HOST:REMOTE_PORT
## Create a tunnel from LOCAL_PORT to REMOTE_PORT on REMOTE_HOST through the bastion host.
##
## --tunnel-target-user=USER Username for the tunnel target (optional)
## --tunnel-target-key=KEY Path to the SSH key file for the tunnel target (optional)

# -e: exit on error
set -e

ROOT="$(realpath "$(dirname "$0")"/..)"
SCRIPTS_DIR="${ROOT}/scripts"

# shellcheck disable=SC1091
. "${SCRIPTS_DIR}/easy-options/easyoptions.sh" || exit

# Constants
DEFAULT_SSH_KEY_NAME="bastion_key"
DEFAULT_SSH_KEY_DIR="$HOME/.ssh"
DEFAULT_BASTION_USER="ubuntu"

# Validate required arguments
if [[ -z "$tag" && -z "$instance_id" ]]; then
echo "Error: Either Bastion host tag or instance ID must be provided."
show_help
exit 1
fi

# Set default values if not provided
SSH_KEY_NAME="${key_name:-$DEFAULT_SSH_KEY_NAME}"
SSH_KEY_DIR="${key_dir:-$DEFAULT_SSH_KEY_DIR}"
SSH_KEY_PATH="$SSH_KEY_DIR/$SSH_KEY_NAME"
SSH_PUBLIC_KEY_PATH="$SSH_KEY_PATH.pub"
BASTION_USER="${bastion_user:-$DEFAULT_BASTION_USER}"

# Check if AWS CLI and Session Manager Plugin are installed
if ! command -v aws &>/dev/null; then
echo "AWS CLI could not be found. Please install it before running this script."
exit 1
fi

if ! command -v session-manager-plugin &>/dev/null; then
echo "Session Manager Plugin could not be found. Please install it before running this script."
exit 1
fi

# Generate SSH key pair if not exists
if [ ! -f "$SSH_KEY_PATH" ]; then
echo "Generating SSH key pair..."
ssh-keygen -t rsa -b 2048 -f "$SSH_KEY_PATH" -N ""
fi

# Retrieve Bastion instance ID if not provided
if [[ -z "$instance_id" ]]; then
echo "Retrieving Bastion instance ID..."
instance_id=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$tag" --query "Reservations[*].Instances[*].InstanceId" --output text)
if [[ -z "$instance_id" ]]; then
echo "No Bastion host found with tag: $tag"
exit 1
fi
echo "Bastion Instance ID: $instance_id"
fi

# Send SSH Public Key
echo "Sending SSH public key to Bastion host..."
aws ec2-instance-connect send-ssh-public-key --instance-id "$instance_id" --instance-os-user "$BASTION_USER" --ssh-public-key file://"$SSH_PUBLIC_KEY_PATH"

# Connect to Bastion Host or create a tunnel using SSH through Session Manager
ssh_proxy_command_option="ProxyCommand sh -c \"aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\""

if [[ -z "$tunnel" ]]; then
echo "Connecting to Bastion host using SSH through Session Manager..."
ssh -i "$SSH_KEY_PATH" -o "$ssh_proxy_command_option" "$BASTION_USER@$instance_id"
echo "Connection to Bastion host established."
exit 0
fi

echo "Creating tunnel through Bastion host to $tunnel..."
if [[ -n "$tunnel_target_user" && -n "$tunnel_target_key" ]]; then
tunnel_host=$(echo "$tunnel" | cut -d':' -f2)
ssh_proxy_command_option="ProxyCommand ssh -i $tunnel_target_key -W %h:%p $tunnel_target_user@$tunnel_host"
ssh_tunnel_proxy_command_option="ProxyCommand ssh -i $tunnel_target_key -W %h:%p $tunnel_target_user@$tunnel_host"
ssh -i "$SSH_KEY_PATH" -o "$ssh_proxy_command_option" -L "$tunnel" -o "$ssh_tunnel_proxy_command_option" -N "$BASTION_USER@$instance_id"
else
ssh -i "$SSH_KEY_PATH" -o "$ssh_proxy_command_option" -L "$tunnel" -N "$BASTION_USER@$instance_id"
fi
echo "Tunnel established through Bastion host."
61 changes: 61 additions & 0 deletions modules/bastion/scripts/easy-options/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# EasyOptions

EasyOptions allows you to write the help text for your program _only once_, and have the described options _automatically parsed_ from command line into easily readable variables, _without complicated API_. EasyOptions was developed after discontentment with the existing solutions for option parsing in Bash. It was conceived with the following guidelines in mind:

- Avoid duplication of source code documentation, help text and options specification.
- Have the option values parsed into easily readable variables.
- Have the non-option arguments available on a simple, separate array.
- Usage as simple as one single line of code.

EasyOptions is going to parse all of your options and arguments automatically once sourced. You specify what options are supported by your program by simply writing a help text, using special double-hash comments. This help text also works at the same time as source code documentation and options specification. All client scripts have an automatic `--help` option, which is going to display such documentation. You can see more details, specially about the options specification, in the help text of EasyOptions itself.

## Usage

For using EasyOptions in your script, simply document it using double-hash comments like this:

```bash
## Program Name v1.0
## Copyright (C) Someone
## Licensed under XYZ
##
## This program does something with the arguments. Usage:
## @script.name [option] ARGUMENTS...
##
## Options:
## -h, --help All client scripts have this, it can be omitted.
## -o, --some-option This is a boolean option. Long version is
## mandatory, and can be specified before or
## after short version.
## --some-boolean This is a boolean option without a short version.
## --some-value=VALUE This is a parameter option. When calling your script
## the equal sign is optional and blank space can be
## used instead. Short version is not available in this
## format.
```

The above comments work both as source code documentation and as help text, as well as define the options supported by your script. There is no duplication of the options specification. The string `@script.name` will be replaced with the actual script name. Now you only need to call EasyOptions in your script and _that's it_!

### Using Arguments

After writing your documentation, you simply source this script. Then all command line options will get parsed into the corresponding variables. You can then check their values for reacting to them. Regular arguments will be available in the `$arguments` array. You can source `easyoptions.sh` for a pure Bash implementation. Here is an example for parsing the comments above:

```bash
ROOT=$(dirname "$0")
source "${ROOT}/easyoptions.sh" || exit # Bash implementation, slower

# Boolean and parameter options
[[ -n "$some_option" ]] && echo "Option specified: --some-option"
[[ -n "$some_boolean" ]] && echo "Option specified: --some-boolean"
[[ -n "$some_value" ]] && echo "Option specified: --some-value is $some_value"

# Arguments
for argument in "${arguments[@]}"; do
echo "Argument specified: $argument"
done
```

If using the pure Bash implementation, then for better speed you may want to define the options in source code yourself, so they do not need to be parsed from the documentation. The side effect is that when changing them, you will need to update both the documentation and the source code. You define the options statically like this:

```bash
options=(o=option some-boolean some-value=?)
```
Loading

0 comments on commit aedb3d4

Please sign in to comment.