-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Flaconi/init
Initial commit
- Loading branch information
Showing
13 changed files
with
698 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
ifneq (,) | ||
.error This Makefile requires GNU Make. | ||
endif | ||
|
||
.PHONY: help gen lint test _gen-main _gen-examples _gen-modules _lint_files _lint_fmt _pull-tf _pull-tf-docs | ||
|
||
CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) | ||
TF_EXAMPLES = $(sort $(dir $(wildcard $(CURRENT_DIR)examples/*/))) | ||
TF_MODULES = $(sort $(dir $(wildcard $(CURRENT_DIR)modules/*/))) | ||
|
||
TF_VERSION = light | ||
TF_DOCS_VERSION = 0.6.0 | ||
|
||
# Adjust your delimiter here or overwrite via make arguments | ||
DELIM_START = <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
DELIM_CLOSE = <!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
|
||
help: | ||
@echo "gen Generate terraform-docs output and replace in all README.md's" | ||
@echo "lint Static source code analysis" | ||
@echo "test Integration tests" | ||
|
||
gen: _pull-tf-docs | ||
@echo "################################################################################" | ||
@echo "# Terraform-docs generate" | ||
@echo "################################################################################" | ||
@$(MAKE) --no-print-directory _gen-main | ||
@$(MAKE) --no-print-directory _gen-examples | ||
@$(MAKE) --no-print-directory _gen-modules | ||
|
||
lint: _pull-tf | ||
@$(MAKE) --no-print-directory _lint_files | ||
@$(MAKE) --no-print-directory _lint_fmt | ||
|
||
test: _pull-tf | ||
@$(foreach example,\ | ||
$(TF_EXAMPLES),\ | ||
DOCKER_PATH="/t/examples/$(notdir $(patsubst %/,%,$(example)))"; \ | ||
echo "################################################################################"; \ | ||
echo "# examples/$$( basename $${DOCKER_PATH} )"; \ | ||
echo "################################################################################"; \ | ||
echo; \ | ||
echo "------------------------------------------------------------"; \ | ||
echo "# Terraform init"; \ | ||
echo "------------------------------------------------------------"; \ | ||
if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ | ||
init \ | ||
-verify-plugins=true \ | ||
-lock=false \ | ||
-upgrade=true \ | ||
-reconfigure \ | ||
-input=false \ | ||
-get-plugins=true \ | ||
-get=true \ | ||
.; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ | ||
exit 1; \ | ||
fi; \ | ||
echo; \ | ||
echo "------------------------------------------------------------"; \ | ||
echo "# Terraform validate"; \ | ||
echo "------------------------------------------------------------"; \ | ||
if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ | ||
validate \ | ||
$(ARGS) \ | ||
.; then \ | ||
echo "OK"; \ | ||
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ | ||
else \ | ||
echo "Failed"; \ | ||
docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ | ||
exit 1; \ | ||
fi; \ | ||
echo; \ | ||
) | ||
|
||
_gen-main: | ||
@echo "------------------------------------------------------------" | ||
@echo "# Main module" | ||
@echo "------------------------------------------------------------" | ||
@if docker run --rm \ | ||
-v $(CURRENT_DIR):/data \ | ||
-e DELIM_START='$(DELIM_START)' \ | ||
-e DELIM_CLOSE='$(DELIM_CLOSE)' \ | ||
cytopia/terraform-docs:$(TF_DOCS_VERSION) \ | ||
terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md README.md; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
exit 1; \ | ||
fi | ||
|
||
_gen-examples: | ||
@$(foreach example,\ | ||
$(TF_EXAMPLES),\ | ||
DOCKER_PATH="examples/$(notdir $(patsubst %/,%,$(example)))"; \ | ||
echo "------------------------------------------------------------"; \ | ||
echo "# $${DOCKER_PATH}"; \ | ||
echo "------------------------------------------------------------"; \ | ||
if docker run --rm \ | ||
-v $(CURRENT_DIR):/data \ | ||
--workdir "/data/$${DOCKER_PATH}" \ | ||
-e DELIM_START='$(DELIM_START)' \ | ||
-e DELIM_CLOSE='$(DELIM_CLOSE)' \ | ||
cytopia/terraform-docs:$(TF_DOCS_VERSION) \ | ||
terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md $${DOCKER_PATH}/README.md; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
exit 1; \ | ||
fi; \ | ||
) | ||
|
||
_gen-modules: | ||
@$(foreach module,\ | ||
$(TF_MODULES),\ | ||
DOCKER_PATH="modules/$(notdir $(patsubst %/,%,$(module)))"; \ | ||
echo "------------------------------------------------------------"; \ | ||
echo "# $${DOCKER_PATH}"; \ | ||
echo "------------------------------------------------------------"; \ | ||
if docker run --rm \ | ||
-v $(CURRENT_DIR):/data \ | ||
-e DELIM_START='$(DELIM_START)' \ | ||
-e DELIM_CLOSE='$(DELIM_CLOSE)' \ | ||
cytopia/terraform-docs:$(TF_DOCS_VERSION) \ | ||
terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md $${DOCKER_PATH}/README.md; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
exit 1; \ | ||
fi; \ | ||
) | ||
|
||
_lint_files: | ||
@# Lint all non-binary files for trailing spaces | ||
@echo "################################################################################" | ||
@echo "# Lint files" | ||
@echo "################################################################################" | ||
@echo | ||
@echo "------------------------------------------------------------" | ||
@echo "# Trailing spaces" | ||
@echo "------------------------------------------------------------" | ||
find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ | ||
| xargs -0 -n1 grep -Il '' \ | ||
| tr '\n' '\0' \ | ||
| xargs -0 -n1 \ | ||
sh -c 'if [ -f "$${1}" ]; then if LC_ALL=C grep --color=always -inHE "^.*[[:blank:]]+$$" "$${1}";then false; else true; fi; fi' -- | ||
@echo | ||
@echo "------------------------------------------------------------" | ||
@echo "# Windows line feeds (CRLF)" | ||
@echo "------------------------------------------------------------" | ||
find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ | ||
| xargs -0 -n1 grep -Il '' \ | ||
| tr '\n' '\0' \ | ||
| xargs -0 -n1 \ | ||
sh -c 'if [ -f "$${1}" ]; then if file "$${1}" | grep --color=always -E "[[:space:]]CRLF[[:space:]].*line"; then false; else true; fi; fi' -- | ||
@echo | ||
@echo "------------------------------------------------------------" | ||
@echo "# Single trailing newline" | ||
@echo "------------------------------------------------------------" | ||
find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ | ||
| xargs -0 -n1 grep -Il '' \ | ||
| tr '\n' '\0' \ | ||
| xargs -0 -n1 \ | ||
sh -c 'if [ -f "$${1}" ]; then if ! (tail -c 1 "$${1}" | grep -Eq "^$$" && tail -c 2 "$${1}" | grep -Eqv "^$$"); then echo "$${1}"; false; else true; fi; fi' -- | ||
@echo | ||
|
||
_lint_fmt: | ||
@# Lint all Terraform files | ||
@echo "################################################################################" | ||
@echo "# Terraform fmt" | ||
@echo "################################################################################" | ||
@echo | ||
@echo "------------------------------------------------------------" | ||
@echo "# *.tf files" | ||
@echo "------------------------------------------------------------" | ||
@if docker run --rm -v "$(CURRENT_DIR):/t:ro" --workdir "/t" hashicorp/terraform:$(TF_VERSION) \ | ||
fmt -check=true -diff=true -write=false -list=true /t; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
exit 1; \ | ||
fi; | ||
@echo | ||
@echo "------------------------------------------------------------" | ||
@echo "# *.tfvars files" | ||
@echo "------------------------------------------------------------" | ||
@if docker run --rm --entrypoint=/bin/sh -v "$(CURRENT_DIR)/terraform:/t:ro" hashicorp/terraform:$(TF_VERSION) \ | ||
-c "find . -name '*.tfvars' -type f -print0 | xargs -0 -n1 terraform fmt -check=true -write=false -diff=true -list=true"; then \ | ||
echo "OK"; \ | ||
else \ | ||
echo "Failed"; \ | ||
exit 1; \ | ||
fi; | ||
@echo | ||
|
||
_pull-tf: | ||
docker pull hashicorp/terraform:$(TF_VERSION) | ||
|
||
_pull-tf-docs: | ||
docker pull cytopia/terraform-docs:$(TF_DOCS_VERSION) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,68 @@ | ||
# terraform-aws-bastion-ssm-iam | ||
AWS Bastion server which can reside in the private subnet utilizing Systems Manager Sessions | ||
# AWS Bastion SSM IAM | ||
|
||
[![Build Status](https://travis-ci.com/Flaconi/terraform-aws-bastion-ssm-iam.svg?branch=master)](https://travis-ci.com/Flaconi/terraform-aws-bastion-ssm-iam) | ||
[![Tag](https://img.shields.io/github/tag/Flaconi/terraform-aws-bastion-ssm-iam.svg)](https://github.com/Flaconi/terraform-aws-bastion-ssm-iam/releases) | ||
[![license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) | ||
|
||
Terraform module which provides a Bastion for AWS utilizing | ||
* Autoscaling group of min/max 1 for resiliency | ||
* AWS SSM Session Manager, this allows users to start a Terminal Session or Tunnel to an instance without the need of public internet access | ||
* ec2-instance-connect, for the creation of temporary ssh keys on the instance | ||
|
||
__NOTE__ Important, this module managed the SSM Document SSM-SessionManagerRunShell, in some cases it already exists. To make sure Terraform is used to maintain this Document please execute: `aws ssm delete-document --name SSM-SessionManagerRunShell`. In case you do not want to overwrite SSM-SessionManagerRunShell, you can use the module directive `create_new_ssm_document` to create a different document name. This document needs to be refered to as follows: `SSM_DOCUMENT_NAME="SSM-SessionManagerRunShell-JKURx" ./ssh_terminal` | ||
|
||
__NOTE__ For this to work you need to install the session manager plugin for the AWSCLI, click (here)[https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html] for more information. | ||
|
||
## Examples | ||
|
||
Check the [examples](examples) directory for installation. | ||
|
||
|
||
## Client | ||
### SSH Terminal | ||
The bash script `client/ssh_terminal` provides a simplified way to ssh to the IAM Bastion, it uses a recent `awscli`-client with ssm terminal support. | ||
|
||
|
||
### SSH Tunnel | ||
The bash script `client/ssh_tunnel` creates an SSH tunnel using the BASTION, it uses a recent `awscli`-client with ssm terminal support and ec2-instance-connect for uploading the SSH Public key to AWS. Make sure the | ||
BASTION has access to the resources it needs access to by modifying the Security Group of the resouce. | ||
|
||
By default the public key file `$HOME/.ssh/id_rsa.pub` will be used for temporary access. The ENVIRONMENT variable `SSH_PUB_KEY_FILE` can be used to set a different public key, as of now AWS does not support ed25519 public keys. | ||
By default the ENVIRONMENT variable AWS_REGION will be used for the `awscli`-tool, if you are using awscli profiles, please provide the correct region by setting the `AWS_REGION`-variable. | ||
If `DEV_LOCAL_PORT` is specified, the ssh tunnel will be created with `DEV_LOCAL_PORT` as local port to connect to, if not a RANDOM port will be used. | ||
|
||
Example: | ||
```bash | ||
./ssh_tunnel private_subnet.isdfjsdf.eu-central-1.rds.amazonaws.com:3306 | ||
``` | ||
|
||
|
||
|
||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|:----:|:-----:|:-----:| | ||
| subnet\_ids | The subnets where the Bastion can reside in, they can be private | list | n/a | yes | | ||
| vpc\_id | The VPC-ID | string | n/a | yes | | ||
| create\_new\_ssm\_document | This module can create a new SSM document for the SSH Terminal | bool | `"false"` | no | | ||
| create\_security\_group | This module can create a security group for the bastion instance by default | bool | `"true"` | no | | ||
| instance\_type | The instance type of the bastion | string | `"t3.nano"` | no | | ||
| log\_retention | The amount of days the logs need to be kept | number | `"30"` | no | | ||
| name | The name to be interpolated, defaults to bastion-ssm-iam | string | `"bastion-ssm-iam"` | no | | ||
| security\_group\_ids | The security group ids which can be given to the bastion instance, defaults to empty | list | `[]` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| ssm\_document\_name | The document name of SSM | | ||
| this\_security\_group\_id | The security group id of the bastion server | | ||
|
||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | ||
|
||
## License | ||
|
||
[MIT](LICENSE) | ||
|
||
Copyright (c) 2019 [Flaconi GmbH](https://github.com/Flaconi) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
REGION="${AWS_REGION:-eu-central-1}" | ||
NAME="${NAME:-bastion-ssm-iam}" | ||
SSM_DOCUMENT_NAME="${SSM_DOCUMENT_NAME:-SSM-SessionManagerRunShell}" | ||
|
||
function print_error { | ||
read line file <<<$(caller) | ||
echo "An error occurred in line $line of file $file:" >&2 | ||
sed "${line}q;d" "$file" >&2 | ||
exit 1 | ||
} | ||
|
||
if ! [ -x "$(command -v jq)" ]; then | ||
trap print_error 'The command jq is required' | ||
fi | ||
|
||
if ! [ -x "$(command -v aws)" ]; then | ||
trap print_error 'The command aws is required' | ||
fi | ||
|
||
if ! [ -x "$(command -v session-manager-plugin)" ]; then | ||
trap print_error 'The command session-manager-plugin is required' | ||
fi | ||
|
||
INSTANCE_ID=$(aws ec2 describe-instances \ | ||
--region "${REGION}" \ | ||
--filter "Name=tag:Name,Values=$NAME" \ | ||
--query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \ | ||
--output text) | ||
|
||
if [ "${INSTANCE_ID}" == "" ];then | ||
trap print_error "No instance with ssm running could be found" | ||
fi | ||
|
||
exec aws ssm start-session --target "${INSTANCE_ID}" --region "${REGION}" --document-name "${SSM_DOCUMENT_NAME}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -euo pipefail | ||
|
||
SSH_PUB_KEY_FILE="${SSH_PUB_KEY_FILE:-$HOME/.ssh/id_rsa.pub}" | ||
REGION="${AWS_REGION:-eu-central-1}" | ||
NAME="${NAME:-bastion-ssm-iam}" | ||
RANDOM_PORT=$(( ( RANDOM % 60000 ) + 1024 )) | ||
DEV_LOCAL_PORT="${DEV_LOCAL_PORT:-$RANDOM_PORT}" | ||
FORWARD_TO=$1 | ||
|
||
function print_error { | ||
read line file <<<$(caller) | ||
echo "An error occurred in line $line of file $file:" >&2 | ||
sed "${line}q;d" "$file" >&2 | ||
exit 1 | ||
} | ||
|
||
if ! [ -x "$(command -v jq)" ]; then | ||
trap print_error 'The command jq is required' | ||
fi | ||
|
||
if ! [ -x "$(command -v aws)" ]; then | ||
trap print_error 'The command aws is required' | ||
fi | ||
|
||
if ! [ -x "$(command -v session-manager-plugin)" ]; then | ||
trap print_error 'The command session-manager-plugin is required' | ||
fi | ||
|
||
if [[ $# -eq 0 ]] ; then | ||
trap print_error "Please provide the hostname:port as argument, for example $0 host_inside_vpc:3306" | ||
fi | ||
|
||
if [ ! -f "$SSH_PUB_KEY_FILE" ] ; then | ||
trap print_error "The ssh public key does not exist" | ||
fi | ||
|
||
|
||
INSTANCE_ID=$(aws ec2 describe-instances \ | ||
--region "${REGION}" \ | ||
--filter "Name=tag:Name,Values=$NAME" \ | ||
--query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \ | ||
--output text) | ||
|
||
AZ=$(aws ec2 describe-instances --region "${REGION}" --filter "Name=tag:Name,Values=$NAME" "Name=instance-state-code,Values=16" --output json| jq -r '.Reservations[].Instances[].Placement.AvailabilityZone') | ||
|
||
if [ "${INSTANCE_ID}" == "" ];then | ||
trap print_error "No instance with ssm running could be found" | ||
fi | ||
|
||
echo -n "Provisioning Bastion SSH Instance with temporary key .... " | ||
aws ec2-instance-connect send-ssh-public-key --region $REGION --instance-id "${INSTANCE_ID}" --availability-zone "${AZ}" --instance-os-user ec2-user --ssh-public-key file://$SSH_PUB_KEY_FILE 2>&1 > /dev/null || trap print_error "Failed" | ||
echo "Success!" | ||
|
||
echo "127.0.0.1:$DEV_LOCAL_PORT is forwarding to $FORWARD_TO" | ||
echo . | ||
echo "Press ctrl-c to exit." | ||
ssh -nNT -o "ProxyCommand=sh -c \"/usr/local/bin/aws ssm --region $REGION start-session --target %h --document-name AWS-StartSSHSession\"" "ec2-user@${INSTANCE_ID}" -L $DEV_LOCAL_PORT:$FORWARD_TO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/sh | ||
|
||
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm | ||
sudo yum install -y ec2-instance-connect | ||
sudo systemctl enable amazon-ssm-agent | ||
sudo systemctl start amazon-ssm-agent |
Oops, something went wrong.