diff --git a/examples/vault-consul-ami/auth/sign-request.py3 b/examples/vault-consul-ami/auth/sign-request.py3 new file mode 100644 index 00000000..c0eb8bd3 --- /dev/null +++ b/examples/vault-consul-ami/auth/sign-request.py3 @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -What------------------------------------------------------------------------- +# This script creates a request to the AWS Security Token Service API +# with the action "GetCallerIdentity" and then signs the request using the +# AWS credentials. It was modified from the python 3.x example published by +# J. Thompson, the author of the Vault IAM auth method, at the vault support +# mailing list. https://gist.github.com/joelthompson/378cbe449d541debf771f5a6a171c5ed +# -Why-------------------------------------------------------------------------- +# We are using python here instead of bash to take advantage of the boto3 library +# which facilitates this work by an order of magnitude +# -What-for--------------------------------------------------------------------- +# This is useful for authenticating to Vault, because a client can use +# this script to generate this request and this request is sent with the +# login attempt to the Vault server. Vault then executes this request and gets +# the response from GetCallerIdentity, which tells who is trying to authenticate +# ------------------------------------------------------------------------------ + +import boto3 +import json +import base64 +import sys + +def headers_to_go_style(headers): + retval = {} + for k, v in headers.items(): + if isinstance(v, bytes): + retval[k] = [str(v, 'ascii')] + else: + retval[k] = [v] + return retval + +def generate_vault_request(awsIamServerId): + session = boto3.session.Session() + # if you have credentials from non-default sources, call + # session.set_credentials here, before calling session.create_client + client = session.client('sts') + endpoint = client._endpoint + operation_model = client._service_model.operation_model('GetCallerIdentity') + request_dict = client._convert_to_request_dict({}, operation_model) + + request_dict['headers']['X-Vault-AWS-IAM-Server-ID'] = awsIamServerId + + request = endpoint.create_request(request_dict, operation_model) + # It's now signed... + return { + 'iam_http_request_method': request.method, + 'iam_request_url': str(base64.b64encode(request.url.encode('ascii')), 'ascii'), + 'iam_request_body': str(base64.b64encode(request.body.encode('ascii')), 'ascii'), + 'iam_request_headers': str(base64.b64encode(bytes(json.dumps(headers_to_go_style(dict(request.headers))), 'ascii')), 'ascii'), # It's a CaseInsensitiveDict, which is not JSON-serializable + } + +if __name__ == "__main__": + awsIamServerId = sys.argv[1] + print(json.dumps(generate_vault_request(awsIamServerId))) diff --git a/examples/vault-consul-ami/vault-consul.json b/examples/vault-consul-ami/vault-consul.json index 8a350c36..f1786f42 100644 --- a/examples/vault-consul-ami/vault-consul.json +++ b/examples/vault-consul-ami/vault-consul.json @@ -13,6 +13,25 @@ "tls_private_key_path": null }, "builders": [{ + "ami_name": "vault-consul-ubuntu20-{{isotime | clean_resource_name}}-{{uuid}}", + "ami_description": "An Ubuntu 20.04 AMI that has Vault and Consul installed.", + "instance_type": "t2.micro", + "name": "ubuntu20-ami", + "region": "{{user `aws_region`}}", + "type": "amazon-ebs", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "architecture": "x86_64", + "name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*", + "block-device-mapping.volume-type": "gp2", + "root-device-type": "ebs" + }, + "owners": ["099720109477"], + "most_recent": true + }, + "ssh_username": "ubuntu" + },{ "ami_name": "vault-consul-ubuntu18-{{isotime | clean_resource_name}}-{{uuid}}", "ami_description": "An Ubuntu 18.04 AMI that has Vault and Consul installed.", "instance_type": "t2.micro", @@ -91,6 +110,10 @@ "type": "file", "source": "{{template_dir}}/auth/sign-request.py", "destination": "/tmp/sign-request.py" + },{ + "type": "file", + "source": "{{template_dir}}/auth/sign-request.py3", + "destination": "/tmp/sign-request.py3" },{ "type": "file", "source": "{{user `ca_public_key_path`}}", @@ -107,9 +130,9 @@ "type": "shell", "inline": [ "if [[ '{{user `install_auth_signing_script`}}' == 'true' ]]; then", - "sudo mv /tmp/sign-request.py /opt/vault/scripts/", + "sudo mv /tmp/sign-request.py* /opt/vault/scripts/", "else", - "sudo rm /tmp/sign-request.py", + "sudo rm /tmp/sign-request.py*", "fi", "sudo mv /tmp/ca.crt.pem /opt/vault/tls/", "sudo mv /tmp/vault.crt.pem /opt/vault/tls/", @@ -131,6 +154,17 @@ ], "inline_shebang": "/bin/bash -e", "only": ["ubuntu16-ami","ubuntu18-ami"] + },{ + "type": "shell", + "inline": [ + "sudo apt-get install -y git", + "if [[ '{{user `install_auth_signing_python3_script`}}' == 'true' ]]; then", + "sudo apt-get install -y python3-pip", + "LC_ALL=C && sudo pip3 install boto3", + "fi" + ], + "inline_shebang": "/bin/bash -e", + "only": ["ubuntu20-ami"] },{ "type": "shell", "inline": [ @@ -160,7 +194,7 @@ ] },{ "type": "shell", - "only": ["ubuntu18-ami"], + "only": ["ubuntu18-ami","ubuntu20-ami"], "inline": [ "/tmp/terraform-aws-consul/modules/setup-systemd-resolved/setup-systemd-resolved" ],