diff --git a/modules/util/assume_role/assumeRole.sh b/modules/util/assume_role/assumeRole.sh new file mode 100755 index 0000000..37d5478 --- /dev/null +++ b/modules/util/assume_role/assumeRole.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh + +# Validate required commands +if ! [ -x "$(command -v aws)" ]; then + echo 'Error: aws is not installed.' >&2 + exit 1 +fi +if ! [ -x "$(command -v jq)" ]; then + echo 'Error: jq is not installed.' >&2 + exit 1 +fi + +# Get the query +TERRAFORM_QUERY=$(jq -Mc .) + +# Extract the query attributes +ASSUME_ROLE_ARN=$(echo "${TERRAFORM_QUERY}" | jq -r '.assume_role_arn') +ROLE_SESSION_NAME=$(echo "${TERRAFORM_QUERY}" | jq -r '.role_session_name') + +aws sts assume-role --output json \ +--role-arn "${ASSUME_ROLE_ARN}" \ +--role-session-name "${ROLE_SESSION_NAME}" \ +--query Credentials \ No newline at end of file diff --git a/modules/util/assume_role/main.tf b/modules/util/assume_role/main.tf new file mode 100644 index 0000000..5555db4 --- /dev/null +++ b/modules/util/assume_role/main.tf @@ -0,0 +1,15 @@ +locals { + assume_role_arn = "arn:aws:iam::${var.account_id}:role/${var.role_name}" +} + +data "external" "awscli" { + program = [format("%s/assumeRole.sh", path.module)] + query = { + assume_role_arn = local.assume_role_arn + role_session_name = var.role_session_name + } +} + +output temp_credential { + value = data.external.awscli.result +} diff --git a/modules/util/assume_role/variables.tf b/modules/util/assume_role/variables.tf new file mode 100644 index 0000000..35882ce --- /dev/null +++ b/modules/util/assume_role/variables.tf @@ -0,0 +1,13 @@ +variable "role_session_name" { + description = "The role session name" + type = string + default = "tf_awscli" +} + +variable account_id { + type = string +} + +variable role_name { + type = string +} \ No newline at end of file diff --git a/modules/util/awscli/README.md b/modules/util/awscli/README.md new file mode 100644 index 0000000..5244779 --- /dev/null +++ b/modules/util/awscli/README.md @@ -0,0 +1,35 @@ +# awscli module +This module executes awscli. Json output goes through base64 encode and decode to work around +terraform map of string requirements for external data. + +## Example root module +```hcl +module "awscli_exec" { + source = "../../modules/util/awscli" + + access_key = module.as_role.temp_credential.AccessKeyId + secret_key = module.as_role.temp_credential.SecretAccessKey + session_token = module.as_role.temp_credential.SessionToken + aws_cli_commands = "ec2 describe-instances --query Reservations[].Instances[].InstanceId" +} + +output awscli_output { + value = module.awscli_exec.awscliout +} +``` + +Sample output +``` +Outputs: + +awscli_output = [ + "i-0cd5e682bc68dbcd2", + "i-050d4adeafaa53cd0", + "i-008328e9dfb56b883", + "i-0634c5ef3528a7b6f", + "i-0dc9009c249f3e3bd", + "i-08034d509751ff058", + "i-0bdd375df2b78a620", + "i-0655d2b3716b1383e", +] +``` \ No newline at end of file diff --git a/modules/util/awscli/awsWithAssumeRole.sh b/modules/util/awscli/awsWithAssumeRole.sh new file mode 100755 index 0000000..f1d16c7 --- /dev/null +++ b/modules/util/awscli/awsWithAssumeRole.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env sh + +# Validate required commands +if ! [ -x "$(command -v aws)" ]; then + echo 'Error: aws is not installed.' >&2 + exit 1 +fi +if ! [ -x "$(command -v jq)" ]; then + echo 'Error: jq is not installed.' >&2 + exit 1 +fi + +# Get the query +TERRAFORM_QUERY=$(jq -Mc .) + +# Extract the query attributes +AWS_CLI_COMMANDS=$(echo "${TERRAFORM_QUERY}" | jq -r '.aws_cli_commands') +AWS_CLI_QUERY=$(echo "${TERRAFORM_QUERY}" | jq -r '.aws_cli_query') +access_key=$(echo "${TERRAFORM_QUERY}" | jq -r '.access_key') +secret_key=$(echo "${TERRAFORM_QUERY}" | jq -r '.secret_key') +session_token=$(echo "${TERRAFORM_QUERY}" | jq -r '.session_token') + +# Do we need to assume a role? +if [ -n "${access_key}" ]; then + export AWS_ACCESS_KEY_ID=$access_key + export AWS_SECRET_ACCESS_KEY=$secret_key + export AWS_SESSION_TOKEN=$session_token +fi + +# Disable any assigned pager +export AWS_PAGER="" + +# Configure adaptive retry mode +# export AWS_RETRY_MODE=adaptive +export AWS_RETRY_MODE=standard +export AWS_MAX_ATTEMPTS=3 + +# Run the AWS_CLI command +aws sts get-caller-identity --query Arn > /tmp/awscli.log +echo '{"awscliout" : "'$(aws ${AWS_CLI_COMMANDS} | base64 -w0)'"}' | tee -a /tmp/awscli.log diff --git a/modules/util/awscli/main.tf b/modules/util/awscli/main.tf new file mode 100644 index 0000000..44aa3bf --- /dev/null +++ b/modules/util/awscli/main.tf @@ -0,0 +1,17 @@ +#locals { +# joined_aws_cli_command = join(" ", var.aws_cli_commands) +#} + +data "external" "awscli_program" { + program = [format("%s/awsWithAssumeRole.sh", path.module)] + query = { + access_key = var.access_key + secret_key = var.secret_key + session_token = var.session_token + aws_cli_commands = var.aws_cli_commands + } +} + +output awscliout { + value = jsondecode(base64decode(data.external.awscli_program.result.awscliout)) +} \ No newline at end of file diff --git a/modules/util/awscli/variables.tf b/modules/util/awscli/variables.tf new file mode 100644 index 0000000..73e8132 --- /dev/null +++ b/modules/util/awscli/variables.tf @@ -0,0 +1,15 @@ +variable "aws_cli_commands" { + type = string +} + +variable access_key { + type = string +} + +variable secret_key { + type = string +} + +variable session_token { + type = string +} \ No newline at end of file