initial commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# acocunt-list module
|
||||
This module returns a list of accounts by querying the aws_organizations_organiation datasource. It returns an accounts map like this
|
||||
|
||||
```
|
||||
{
|
||||
account-name-1 = "111111111111"
|
||||
account-name-2 = "111111111111"
|
||||
}
|
||||
```
|
||||
|
||||
In the root module, query the account id like this
|
||||
```terraform
|
||||
output result {
|
||||
value = lookup(module.account-list.accounts, "account-name-1")
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,2 @@
|
||||
data "aws_organizations_organization" "org" {}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
output accounts {
|
||||
value = zipmap(data.aws_organizations_organization.org.accounts[*].name, data.aws_organizations_organization.org.accounts[*].id)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = "~> 1.2.5"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 4.22"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# assume_role module
|
||||
This module uses awscli, calls sts and obtain temp credentials for role switching. Returns the temp credential as a map.
|
||||
|
||||
## System requirements
|
||||
* awscli
|
||||
* jq
|
||||
|
||||
## Inputs
|
||||
| variable | type | required | description |
|
||||
|:------------------|--------|----------|----------------------------------------------------------------------------|
|
||||
| account_id | string | yes | target aws account id |
|
||||
| role_name | string | yes | target role name |
|
||||
| role_session_name | string | no | session name, useful for tracing logs in cloudtrail. defaults to tf_awscli |
|
||||
|
||||
## Outputs
|
||||
| variable | type | sensitive | description |
|
||||
|-----------------|---------------|-----------|-------------------------|
|
||||
| temp_credential | map of string | yes | json output from awscli |
|
||||
|
||||
```json
|
||||
{
|
||||
"AccessKeyId": "111",
|
||||
"SecretAccessKey": "222",
|
||||
"SessionToken": "333",
|
||||
"Expiration": "2023-07-01T10:19:47+00:00"
|
||||
}
|
||||
```
|
||||
|
||||
# References
|
||||
This module is based on https://registry.terraform.io/modules/digitickets/cli/aws/latest
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# tell bash to exit if any subcommand fails
|
||||
set -eo pipefail
|
||||
|
||||
# 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
|
||||
@@ -0,0 +1,12 @@
|
||||
data "external" "awscli" {
|
||||
program = [format("%s/assumeRole.sh", path.module)]
|
||||
query = {
|
||||
assume_role_arn = "arn:aws:iam::${var.account_id}:role/${var.role_name}"
|
||||
role_session_name = var.role_session_name
|
||||
}
|
||||
}
|
||||
|
||||
output temp_credential {
|
||||
value = data.external.awscli.result
|
||||
sensitive = true
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# aws-region-short module
|
||||
Module which returns a map of aws regions and their short code.
|
||||
|
||||
## Example root module
|
||||
```terraform
|
||||
module region-short {
|
||||
source = "git::https://xpk.headdesk.me/git/xpk/terraform.aws-baseline-infra//modules/util/aws-region-short"
|
||||
}
|
||||
|
||||
output region-short-code {
|
||||
value = lookup(module.region-short.region-map, var.aws-region)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
output "region-map" {
|
||||
value = local.region-map
|
||||
}
|
||||
|
||||
locals {
|
||||
region-map = {
|
||||
ap-northeast-1 = "apne1"
|
||||
ap-northeast-2 = "apne2"
|
||||
ap-northeast-3 = "apne3"
|
||||
ap-south-1 = "aps1"
|
||||
ap-southeast-1 = "apse1"
|
||||
ap-southeast-2 = "apse2"
|
||||
ca-central-1 = "cac1"
|
||||
eu-central-1 = "euc1"
|
||||
eu-north-1 = "eun1"
|
||||
eu-west-1 = "euw1"
|
||||
eu-west-2 = "euw2"
|
||||
eu-west-3 = "euw3"
|
||||
sa-east-1 = "sae1"
|
||||
us-east-1 = "use1"
|
||||
us-east-2 = "use2"
|
||||
us-west-1 = "usw1"
|
||||
us-west-2 = "usw2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
terraform {
|
||||
required_version = "~> 1.2.5"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 3.75.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
# awscli module
|
||||
This module executes awscli and returns the output.
|
||||
|
||||
# input variables
|
||||
Set the temp credentials if role switching is needed. Otherwise, leave them alone.
|
||||
|
||||
| variable | type | required | description |
|
||||
|------------------|---------|----------|-------------------------------------|
|
||||
| access_key | string | no | for role switching |
|
||||
| secret_key | string | no | for role switching |
|
||||
| session_token | string | no | for role switching |
|
||||
| aws_cli_commands | string | yes | command and parameters after `aws` |
|
||||
|
||||
# output variable
|
||||
Normally terraform only produces a simple map of string in output. To work
|
||||
around this, awscli outout are base64 encoded. The output variable is then
|
||||
base64decoded back to the original text.
|
||||
|
||||
| variable | type | description |
|
||||
|:--------------|:-------|:-------------------|
|
||||
| awscli_output | string | output from awscli |
|
||||
|
||||
## Usage example
|
||||
```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
|
||||
}
|
||||
```
|
||||
|
||||
Output
|
||||
```
|
||||
Outputs:
|
||||
|
||||
awscli_output = [
|
||||
"i-0cd5e682bc68dbcd2",
|
||||
"i-050d4adeafaa53cd0",
|
||||
"i-008328e9dfb56b883",
|
||||
"i-0634c5ef3528a7b6f",
|
||||
"i-0dc9009c249f3e3bd",
|
||||
"i-08034d509751ff058",
|
||||
"i-0bdd375df2b78a620",
|
||||
"i-0655d2b3716b1383e",
|
||||
]
|
||||
```
|
||||
|
||||
# References
|
||||
This module is based on https://registry.terraform.io/modules/digitickets/cli/aws/latest
|
||||
@@ -0,0 +1,14 @@
|
||||
data "external" "awscli_program" {
|
||||
program = [format("%s/run_awscli.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
|
||||
}
|
||||
}
|
||||
|
||||
# decode encapsulated string back to original
|
||||
output awscliout {
|
||||
value = jsondecode(base64decode(data.external.awscli_program.result.awscliout))
|
||||
}
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# tell bash to exit if any subcommand fails
|
||||
set -eo pipefail
|
||||
|
||||
# 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
|
||||
|
||||
# Process inputs
|
||||
TERRAFORM_QUERY=$(jq -Mc .)
|
||||
AWS_CLI_COMMANDS=$(echo "${TERRAFORM_QUERY}" | jq -r '.aws_cli_commands')
|
||||
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')
|
||||
|
||||
# Set temp credentials if provided
|
||||
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
|
||||
|
||||
# awscli options
|
||||
export AWS_PAGER="" # disable pager
|
||||
export AWS_RETRY_MODE=standard # adaptive causes throttling, use standard for now
|
||||
export AWS_MAX_ATTEMPTS=3 # default is 2
|
||||
|
||||
# Run the awscli command, encapsulate output in base64
|
||||
jq -n --arg jqarg1 "$(aws ${AWS_CLI_COMMANDS})" '{ "awscliout" : $jqarg1 | @base64 }'
|
||||
@@ -0,0 +1,18 @@
|
||||
variable "aws_cli_commands" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "access_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "secret_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "session_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
resource "random_string" "string" {
|
||||
length = 4
|
||||
special = false
|
||||
}
|
||||
|
||||
resource "random_integer" "number" {
|
||||
min = 1000
|
||||
max = 9999
|
||||
}
|
||||
|
||||
output "string" {
|
||||
value = random_string.string.result
|
||||
}
|
||||
|
||||
output "number" {
|
||||
value = random_integer.number.result
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# resource-list module
|
||||
Module for listing resources, where native terraform data source is not available.
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "export lb=\(.input) asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws elbv2 describe-target-groups --load-balancer-arn $lb --query TargetGroups[*].TargetGroupArn --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
RESULTS=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?Type==`application`].LoadBalancerArn' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
# exclude ASG instances
|
||||
RESULTS=$(aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[*].AutoScalingGroupName' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# exclude ASG instances
|
||||
RESULTS=$(aws ec2 describe-instances --query 'Reservations[].Instances[?!not_null(Tags[?Key == `aws:autoscaling:groupName`].Value)].InstanceId' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws emr list-clusters --active --query Clusters[*].ClusterArn --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws kafka list-clusters --query ClusterInfoList[*].ClusterName --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
RESULTS=$(aws ec2 describe-nat-gateways --query 'NatGateways[].NatGatewayId' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "export lb=\(.input) asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws elbv2 describe-target-groups --load-balancer-arn $lb --query TargetGroups[*].TargetGroupArn --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
RESULTS=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?Type==`network`].LoadBalancerArn' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws opensearch list-domain-names --query DomainNames[*].DomainName --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
RESULTS=$(aws rds describe-db-instances --query 'DBInstances[*].DBInstanceIdentifier' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
eval "$(jq -r '@sh "asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$( aws elasticache describe-cache-clusters --query 'CacheClusters[*].CacheClusterId' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
eval "$(jq -r '@sh "asrolearn=\(.asrolearn)"')"
|
||||
eval "$(aws sts assume-role --role-arn $asrolearn --role-session-name awscli | jq -cr '"export AWS_ACCESS_KEY_ID=" + .Credentials.AccessKeyId, "export AWS_SECRET_ACCESS_KEY=" + .Credentials.SecretAccessKey, "export AWS_SESSION_TOKEN=" + .Credentials.SessionToken')"
|
||||
|
||||
RESULTS=$(aws ec2 describe-transit-gateways --query 'TransitGateways[].TransitGatewayId' --output text --no-cli-pager | sed 's/\t/\n/g' | sort | xargs)
|
||||
jq -n --arg result "$RESULTS" '{"result":$result}'
|
||||
@@ -0,0 +1,13 @@
|
||||
data "external" "instances" {
|
||||
program = ["bash", "${path.module}/list-${var.resource-type}.sh"]
|
||||
query = {
|
||||
input = var.query-input
|
||||
asrolearn = var.asrolearn
|
||||
}
|
||||
}
|
||||
|
||||
output result-set {
|
||||
# value = toset(split(" ", data.external.instances.result.result))
|
||||
# prevents terraform from returning [""]
|
||||
value = length(data.external.instances.result.result) > 0 ? toset(split(" ", data.external.instances.result.result)) : []
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
variable resource-type {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable query-input {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable asrolearn {
|
||||
type = string
|
||||
|
||||
validation {
|
||||
condition = length(var.asrolearn) > 1
|
||||
error_message = "asrolearn is too short"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/test-reports/
|
||||
.idea/
|
||||
/PersonalSettingsMakefile
|
||||
.terraform/
|
||||
/temp/
|
||||
@@ -0,0 +1,43 @@
|
||||
repos:
|
||||
- repo: https://github.com/antonbabenko/pre-commit-terraform
|
||||
rev: v1.77.2
|
||||
hooks:
|
||||
- id: terraform_tflint
|
||||
- id: terraform_fmt
|
||||
- id: terraform_validate
|
||||
exclude: modules
|
||||
- id: terraform_docs
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-json
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-yaml
|
||||
- id: detect-aws-credentials
|
||||
args:
|
||||
- --allow-missing-credentials
|
||||
- id: detect-private-key
|
||||
- id: end-of-file-fixer
|
||||
- id: fix-byte-order-marker
|
||||
- id: pretty-format-json
|
||||
files: .*\.json$
|
||||
args:
|
||||
- --autofix
|
||||
- --indent=2
|
||||
- --no-sort-keys
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
|
||||
rev: 0.2.2
|
||||
hooks:
|
||||
- id: yamlfmt
|
||||
args:
|
||||
- --implicit_start
|
||||
- --preserve-quotes
|
||||
- --mapping=2
|
||||
- --offset=2
|
||||
- --sequence=4
|
||||
- --width=300
|
||||
@@ -0,0 +1 @@
|
||||
1.4.5
|
||||
@@ -0,0 +1,32 @@
|
||||
config {
|
||||
module = true
|
||||
force = false
|
||||
}
|
||||
|
||||
// Only the AWS plugin is enabled. The Google and Azure plugins are not enabled as we have no current use for them.
|
||||
plugin "aws" {
|
||||
enabled = true
|
||||
source = "github.com/terraform-linters/tflint-ruleset-aws"
|
||||
version = "0.22.1"
|
||||
deep_check = true
|
||||
}
|
||||
|
||||
rule "terraform_naming_convention" {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
rule "terraform_deprecated_interpolation" {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
rule "terraform_documented_outputs" {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
rule "terraform_documented_variables" {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
rule "terraform_module_pinned_source" {
|
||||
enabled = true
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
install:
|
||||
- sudo apt-get -y install jq
|
||||
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
- unzip awscliv2.zip
|
||||
- sudo ./aws/install
|
||||
- git clone https://github.com/tfutils/tfenv.git ~/.tfenv
|
||||
- sudo ln -s ~/.tfenv/bin/* /usr/local/bin
|
||||
- tfenv install
|
||||
|
||||
script:
|
||||
- terraform init
|
||||
- tests/tests.sh
|
||||
@@ -0,0 +1,86 @@
|
||||
# Changelog
|
||||
|
||||
# v5.0.4 - 2022/11/28
|
||||
|
||||
- Allow `var.role_session_name` to be optional. Thank you [Byron Kim](https://github.com/digitickets/terraform-aws-cli/issues/4)
|
||||
|
||||
# v5.0.3 - 2022/05/31
|
||||
|
||||
- Fix for when the AWS call being made has no output (which is invalid JSON). Thank you [Yaron Yarimi and Pavel Kargin](https://github.com/digitickets/terraform-aws-cli/issues/3)
|
||||
|
||||
# v5.0.2 - 2022/05/26
|
||||
|
||||
- Fix for when this module is used in an iteration.
|
||||
|
||||
# v5.0.1 - 2022/05/24
|
||||
|
||||
- Explicitly specify output type as json for assume role call. Thank you [Niranjan Rajendran](https://github.com/digitickets/terraform-aws-cli/pull/2)
|
||||
|
||||
# v5.0.0 - 2022/01/27
|
||||
|
||||
- Fixed incompatibilities with Terraform 1.1.0.
|
||||
|
||||
# v4.1.0 - 2021/10/05
|
||||
|
||||
- Validate role_session_name so that the maximum length is 64 characters and that it must match a specific regex.
|
||||
|
||||
# v4.0.0 - 2021/05/18
|
||||
|
||||
- Set minimum terraform version to 0.15.0.
|
||||
|
||||
# No release required - 2021/03/30
|
||||
|
||||
- Updated tests to use an AWS request that does not require credentials, allowing the full terraform plan and apply
|
||||
process to be run and tested with the module.
|
||||
|
||||
# v3.1.1 - 2021/03/25
|
||||
|
||||
- Re-releasing as accidentally released v3.0.0 as v3.1.0.
|
||||
|
||||
# v3.1.0 - 2021/03/25
|
||||
|
||||
- Add an optional `debug_log_filename` variable. If supplied, a log file will be produced in the supplied location. This
|
||||
option enables the `--debug` option of the AWS CLI. Use this in safe environments as potentially sensitive content may
|
||||
be logged.
|
||||
- Added [adaptive retry mode](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html#cli-usage-retries-modes-adaptive)
|
||||
to help alleviate throttling issues.
|
||||
|
||||
# v3.0.0 - 2020/12/03
|
||||
|
||||
- Set minimum terraform version to 0.14.0.
|
||||
- Introduced `.terraform.lock.hcl` for versioning of dependencies.
|
||||
|
||||
# v2.0.1 - 2020/09/17
|
||||
|
||||
- Add `depends_on` to enforce the order in which the resources get instantiated / evaluated.
|
||||
|
||||
# v2.0.0 - 2020/09/17
|
||||
|
||||
- Set minimum terraform version to 0.13.0
|
||||
- Added variable validation to optional `assume_role_arn` to match syntax described in
|
||||
[IAM Identifiers](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html).
|
||||
|
||||
# v1.3.0 - 2020/08/03
|
||||
|
||||
- Set minimum version of random provider to 2.3.0
|
||||
|
||||
# v1.2.2 - 2020/05/11
|
||||
|
||||
- Updated examples in [README.md](README.md).
|
||||
|
||||
# v1.2.1 - 2020/05/11
|
||||
|
||||
- Updated [README.md](README.md) to reflect `digiticketsgroup/terraforming` image that includes all the required
|
||||
resources for using this module.
|
||||
|
||||
# v1.2.0 - 2020/05/11
|
||||
|
||||
- Drop down to using `sh` rather than `bash` so this module can operate with Hashicorp Terraform Docker image.
|
||||
|
||||
# v1.1.0 - 2020/05/07
|
||||
|
||||
- Updated examples in README.md with registry path as displayed by registry.
|
||||
- Updated `assume_role_arn` to reflect that it is optional.
|
||||
|
||||
# v1.0.0 - 2020/05/07
|
||||
Initial release
|
||||
@@ -0,0 +1,131 @@
|
||||
[](https://travis-ci.com/digitickets/terraform-aws-cli)
|
||||
[](https://github.com/digitickets/terraform-aws-cli/issues)
|
||||
|
||||
# terraform-aws-cli
|
||||
|
||||
Run the AWS CLI, with the ability to run under an assumed role, to access resources and properties missing from the
|
||||
Terraform AWS Provider.
|
||||
|
||||
# Requirements
|
||||
|
||||
This module requires a couple of additional resources to operate successfully.
|
||||
|
||||
1. Amazon Web Service Command Line Interface (awscli)
|
||||
: This is available in several forms [here](https://aws.amazon.com/cli/).
|
||||
|
||||
2. JSON processor (jq)
|
||||
: This is available [here](https://stedolan.github.io/jq/).
|
||||
|
||||
# Examples
|
||||
|
||||
## 1. Get the desired capacity of an autoscaling group.
|
||||
|
||||
If you are using a blue/green style deployment, you would want to create the same number of EC2 instances as you are
|
||||
replacing.
|
||||
|
||||
```hcl-terraform
|
||||
module "current_desired_capacity" {
|
||||
source = "digitickets/cli/aws"
|
||||
role_session_name = "GettingDesiredCapacityFor${var.environment}"
|
||||
aws_cli_commands = ["autoscaling", "describe-auto-scaling-groups"]
|
||||
aws_cli_query = "AutoScalingGroups[?Tags[?Key==`Name`]|[?Value==`digitickets-${var.environment}-asg-app`]]|[0].DesiredCapacity"
|
||||
}
|
||||
```
|
||||
|
||||
You can now set the desired capacity of an aws_autoscaling_group:
|
||||
|
||||
```hcl-terraform
|
||||
desired_capacity = module.current_desired_capacity.result
|
||||
```
|
||||
|
||||
## 2. Assuming a role.
|
||||
|
||||
Extending the first example above, assuming a role is as simple as adding an `assume_role_arn` to the module:
|
||||
|
||||
```hcl-terraform
|
||||
module "current_desired_capacity" {
|
||||
source = "digitickets/cli/aws"
|
||||
assume_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/OrganizationAccountAccessRole"
|
||||
role_session_name = "GettingDesiredCapacityFor${var.environment}"
|
||||
aws_cli_commands = ["autoscaling", "describe-auto-scaling-groups"]
|
||||
aws_cli_query = "AutoScalingGroups[?Tags[?Key==`Name`]|[?Value==`digitickets-${var.environment}-asg-app`]]|[0].DesiredCapacity"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.15 |
|
||||
| <a name="requirement_external"></a> [external](#requirement\_external) | ~> 2.0 |
|
||||
| <a name="requirement_local"></a> [local](#requirement\_local) | ~> 2.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| <a name="provider_external"></a> [external](#provider\_external) | 2.3.1 |
|
||||
| <a name="provider_local"></a> [local](#provider\_local) | 2.4.0 |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [external_external.awscli_program](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |
|
||||
| [local_file.awscli_results_file](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| <a name="input_assume_role_arn"></a> [assume\_role\_arn](#input\_assume\_role\_arn) | The ARN of the role being assumed (optional) | `string` | `""` | no |
|
||||
| <a name="input_aws_cli_commands"></a> [aws\_cli\_commands](#input\_aws\_cli\_commands) | The AWS CLI command and subcommands | `list(string)` | n/a | yes |
|
||||
| <a name="input_aws_cli_query"></a> [aws\_cli\_query](#input\_aws\_cli\_query) | The --query value | `string` | `""` | no |
|
||||
| <a name="input_debug_log_filename"></a> [debug\_log\_filename](#input\_debug\_log\_filename) | Generate a debug log if a `debug_log_filename` is supplied | `string` | `""` | no |
|
||||
| <a name="input_role_session_name"></a> [role\_session\_name](#input\_role\_session\_name) | The role session name | `string` | `""` | no |
|
||||
|
||||
## Outputs
|
||||
|
||||
| Name | Description |
|
||||
|------|-------------|
|
||||
| <a name="output_result"></a> [result](#output\_result) | The output of the AWS CLI command |
|
||||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
|
||||
|
||||
# Docker
|
||||
|
||||
To help with getting this running in a pipeline that uses Docker, the image [digiticketsgroup/terraforming](https://hub.docker.com/repository/docker/digiticketsgroup/terraforming) has Terraform, AWSCLI, and jq all ready to go.
|
||||
|
||||
If you want to build or adapt your own image, then the Dockerfile below is how that image has been built.
|
||||
|
||||
```Dockerfile
|
||||
# Based upon https://github.com/aws/aws-cli/blob/2.0.10/docker/Dockerfile
|
||||
FROM amazonlinux:2 as installer
|
||||
ARG TERRAFORM_VERSION
|
||||
RUN yum update -y \
|
||||
&& yum install -y unzip \
|
||||
&& curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscli-exe-linux-x86_64.zip \
|
||||
&& unzip awscli-exe-linux-x86_64.zip \
|
||||
# The --bin-dir is specified so that we can copy the
|
||||
# entire bin directory from the installer stage into
|
||||
# into /usr/local/bin of the final stage without
|
||||
# accidentally copying over any other executables that
|
||||
# may be present in /usr/local/bin of the installer stage.
|
||||
&& ./aws/install --bin-dir /aws-cli-bin/ \
|
||||
&& curl "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" -o terraform.zip \
|
||||
&& unzip terraform.zip
|
||||
|
||||
FROM amazonlinux:2
|
||||
COPY --from=installer /usr/local/aws-cli/ /usr/local/aws-cli/
|
||||
COPY --from=installer /aws-cli-bin/ /usr/local/bin/
|
||||
COPY --from=installer terraform /usr/bin/
|
||||
RUN yum update -y \
|
||||
&& yum install -y less groff jq \
|
||||
&& yum clean all
|
||||
|
||||
ENTRYPOINT ["/bin/sh"]
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
locals {
|
||||
joined_aws_cli_command = join(" ", var.aws_cli_commands)
|
||||
output_file = format(
|
||||
"%s/temp/results-%s.json",
|
||||
path.module,
|
||||
md5(
|
||||
join(
|
||||
"-",
|
||||
[
|
||||
var.assume_role_arn,
|
||||
var.role_session_name,
|
||||
local.joined_aws_cli_command,
|
||||
var.aws_cli_query,
|
||||
var.debug_log_filename
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
data "external" "awscli_program" {
|
||||
program = [format("%s/scripts/awsWithAssumeRole.sh", path.module)]
|
||||
query = {
|
||||
assume_role_arn = var.assume_role_arn
|
||||
role_session_name = var.role_session_name
|
||||
aws_cli_commands = local.joined_aws_cli_command
|
||||
aws_cli_query = var.aws_cli_query
|
||||
output_file = local.output_file
|
||||
debug_log_filename = var.debug_log_filename
|
||||
}
|
||||
}
|
||||
|
||||
data "local_file" "awscli_results_file" {
|
||||
depends_on = [data.external.awscli_program]
|
||||
filename = data.external.awscli_program.query.output_file
|
||||
}
|
||||
|
||||
output "result" {
|
||||
depends_on = [data.local_file.awscli_results_file]
|
||||
description = "The output of the AWS CLI command"
|
||||
value = try(jsondecode(data.local_file.awscli_results_file.content), null)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#!/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')
|
||||
OUTPUT_FILE=$(echo "${TERRAFORM_QUERY}" | jq -r '.output_file')
|
||||
ASSUME_ROLE_ARN=$(echo "${TERRAFORM_QUERY}" | jq -r '.assume_role_arn')
|
||||
ROLE_SESSION_NAME=$(echo "${TERRAFORM_QUERY}" | jq -r '.role_session_name')
|
||||
DEBUG_LOG_FILENAME=$(echo "${TERRAFORM_QUERY}" | jq -r '.debug_log_filename')
|
||||
|
||||
# Do we need to assume a role?
|
||||
if [ -n "${ASSUME_ROLE_ARN}" ]; then
|
||||
TEMP_ROLE=$(aws sts assume-role --output json --role-arn "${ASSUME_ROLE_ARN}" --role-session-name "${ROLE_SESSION_NAME:-AssumingRole}")
|
||||
export AWS_ACCESS_KEY_ID=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.AccessKeyId')
|
||||
export AWS_SECRET_ACCESS_KEY=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SecretAccessKey')
|
||||
export AWS_SESSION_TOKEN=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SessionToken')
|
||||
fi
|
||||
|
||||
# Do we have a query?
|
||||
if [ -n "${AWS_CLI_QUERY}" ]; then
|
||||
AWS_CLI_QUERY_PARAM="--query '${AWS_CLI_QUERY}'"
|
||||
fi
|
||||
|
||||
# Do we want to be debug?
|
||||
export AWS_DEBUG_OPTION=""
|
||||
if [ -n "${DEBUG_LOG_FILENAME}" ]; then
|
||||
AWS_DEBUG_OPTION="--debug 2>${DEBUG_LOG_FILENAME}"
|
||||
mkdir -p "$(dirname ${DEBUG_LOG_FILENAME})"
|
||||
fi
|
||||
|
||||
# Make sure output file directory exists
|
||||
mkdir -p "$(dirname ${OUTPUT_FILE})"
|
||||
|
||||
# Make sure output file does not exist
|
||||
rm -f "${OUTPUT_FILE}"
|
||||
|
||||
# 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, exiting with a non zero exit code if required.
|
||||
if ! eval "aws ${AWS_CLI_COMMANDS} ${AWS_CLI_QUERY_PARAM:-} --output json ${AWS_DEBUG_OPTION}" >"${OUTPUT_FILE}" ; then
|
||||
echo "Error: aws failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# All is good.
|
||||
echo '{"output_file":"'"${OUTPUT_FILE}"'"}'
|
||||
@@ -0,0 +1,3 @@
|
||||
assume_role_arn = "bad_arn"
|
||||
aws_cli_commands = ["version"]
|
||||
role_session_name = "bad_arn"
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ -f $PLAN_FILE ]]; then
|
||||
echo "Incorrectly generated a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! -z "$(cat $PLAN_LOG_FILE)" ]]; then
|
||||
echo "Incorrectly generated content in the plan log file - $PLAN_LOG_FILE";
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
if [[ ! "$(cat $PLAN_ERROR_FILE)" == *'The optional ARN must match the format documented in'* ]]; then
|
||||
echo 'Failed to detect invalid ARN.';
|
||||
exit 3;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TEST_PATH=$(dirname $1)
|
||||
TEST_NAME=$(basename $TEST_PATH)
|
||||
|
||||
echo "Start : $TEST_PATH"
|
||||
|
||||
TERRAFORM_TFVARS=$TEST_PATH/terraform.tfvars
|
||||
EXPECTED_VARIABLES=$TEST_PATH/expected_variables.json
|
||||
|
||||
RESOURCE_PATH=test-reports/$TEST_NAME
|
||||
mkdir -p $RESOURCE_PATH
|
||||
|
||||
INIT_LOG_FILE=$RESOURCE_PATH/init.log
|
||||
INIT_ERROR_FILE=$RESOURCE_PATH/init.error.log
|
||||
PLAN_FILE=$RESOURCE_PATH/terraform.plan
|
||||
PLAN_LOG_FILE=$RESOURCE_PATH/plan.log
|
||||
PLAN_ERROR_FILE=$RESOURCE_PATH/plan.error.log
|
||||
STATE_FILE=$RESOURCE_PATH/terraform.tfstate
|
||||
APPLY_LOG_FILE=$RESOURCE_PATH/apply.log
|
||||
APPLY_ERROR_FILE=$RESOURCE_PATH/apply.error.log
|
||||
DEBUG_LOG_FILE=$RESOURCE_PATH/debug.log
|
||||
|
||||
terraform init > $INIT_LOG_FILE 2> $INIT_ERROR_FILE
|
||||
|
||||
terraform plan -var-file=$TERRAFORM_TFVARS -out=$PLAN_FILE > $PLAN_LOG_FILE 2> $PLAN_ERROR_FILE
|
||||
|
||||
run_test
|
||||
|
||||
echo "Passed : $TEST_PATH"
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"assume_role_arn": {
|
||||
"value": ""
|
||||
},
|
||||
"aws_cli_commands": {
|
||||
"value": [
|
||||
"guardduty",
|
||||
"update-detector",
|
||||
"--finding-publishing-frequency",
|
||||
"ONE_HOUR",
|
||||
"--detector-id",
|
||||
"0123456789abcdef0123456789abcdef"
|
||||
]
|
||||
},
|
||||
"aws_cli_query": {
|
||||
"value": ""
|
||||
},
|
||||
"debug_log_filename": {
|
||||
"value": ""
|
||||
},
|
||||
"role_session_name": {
|
||||
"value": "empty_result"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
This test requires Guard Duty. As this is a paid service, the test is disabled.
|
||||
|
||||
The test can be enabled by running the following commands with a suitable profile or set of AWS credentials in play.
|
||||
|
||||
1. Create the Guard Duty detector
|
||||
|
||||
aws guardduty create-detector --enable
|
||||
|
||||
|
||||
2. Get the detector ID
|
||||
|
||||
aws guardduty list-detectors --query='DetectorIds[0]'
|
||||
|
||||
|
||||
3. Copy the detector ID reported into terraform.tfvars and update the expected_variables.json file to match, replacing
|
||||
0123456789abcdef0123456789abcdef (unless that's your detector ID of course! ... It COULD happen!)
|
||||
|
||||
|
||||
4. Change the RUN_TEST to true in ./test.sh
|
||||
|
||||
|
||||
Once you've finished the testing, revert the changes above, and disable the detector using
|
||||
|
||||
aws guardduty delete-detector --detector-id <detector_id>
|
||||
|
||||
replacing <detector_id> with the detector ID you extracted in step 2 above.
|
||||
@@ -0,0 +1,3 @@
|
||||
// An empty result from AWS
|
||||
aws_cli_commands = ["guardduty", "update-detector", "--finding-publishing-frequency", "ONE_HOUR", "--detector-id", "0123456789abcdef0123456789abcdef"]
|
||||
role_session_name = "empty_result"
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ ! -f $PLAN_FILE ]]; then
|
||||
echo "Failed to generate a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! "$(terraform show -json $PLAN_FILE | jq -MSr .variables)" == "$(cat $EXPECTED_VARIABLES)" ]]; then
|
||||
echo 'Failed to incorporate expected variable values into plan.';
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
terraform apply -auto-approve -backup=- -state-out $STATE_FILE -var-file $TERRAFORM_TFVARS > $APPLY_LOG_FILE 2> $APPLY_ERROR_FILE
|
||||
|
||||
if [[ ! -f $STATE_FILE ]]; then
|
||||
echo "Failed to generate state file - $STATE_FILE";
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# Validate the presence of the plan error file.
|
||||
if [[ ! -f $PLAN_ERROR_FILE ]]; then
|
||||
echo "Failed to generate plan error file - $PLAN_ERROR_FILE";
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# Validate the plan error file is empty.
|
||||
if [[ -s $PLAN_ERROR_FILE ]]; then
|
||||
echo "Plan error file is not empty - $PLAN_ERROR_FILE";
|
||||
exit 5;
|
||||
fi
|
||||
}
|
||||
|
||||
# Set to true to allow this test to run
|
||||
RUN_TEST=false
|
||||
if [[ "$RUN_TEST" == "false" ]]; then
|
||||
echo "Start : $(dirname $0)";
|
||||
echo "Skipped : $(dirname $0) : See $(dirname $0)/notes.txt";
|
||||
else
|
||||
. tests/common.sh $0
|
||||
fi
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// 64 characters, but $ is invalid
|
||||
role_session_name = "$234567890123456789012345678901234567890123456789012345678901234"
|
||||
aws_cli_commands = ["version"]
|
||||
debug_log_filename = "test-reports/role_session_name_invalid_characters/debug.log"
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ -f $PLAN_FILE ]]; then
|
||||
echo "Incorrectly generated a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! -z "$(cat $PLAN_LOG_FILE)" ]]; then
|
||||
echo "Incorrectly generated content in the plan log file - $PLAN_LOG_FILE";
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
if [[ ! "$(cat $PLAN_ERROR_FILE)" == *'The role session name match the regular expression'* ]]; then
|
||||
echo 'Failed to detect invalid characters in role_session_name.';
|
||||
exit 3;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"assume_role_arn": {
|
||||
"value": ""
|
||||
},
|
||||
"aws_cli_commands": {
|
||||
"value": [
|
||||
"s3api",
|
||||
"list-objects",
|
||||
"--bucket",
|
||||
"ryft-public-sample-data",
|
||||
"--no-sign-request"
|
||||
]
|
||||
},
|
||||
"aws_cli_query": {
|
||||
"value": "max_by(Contents, &Size)"
|
||||
},
|
||||
"debug_log_filename": {
|
||||
"value": ""
|
||||
},
|
||||
"role_session_name": {
|
||||
"value": ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// ryft-public-sample-data is a publicly accessible S3 bucket.
|
||||
aws_cli_commands = ["s3api", "list-objects", "--bucket", "ryft-public-sample-data", "--no-sign-request"]
|
||||
aws_cli_query = "max_by(Contents, &Size)"
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ ! -f $PLAN_FILE ]]; then
|
||||
echo "Failed to generate a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! "$(terraform show -json $PLAN_FILE | jq -MSr .variables)" == "$(cat $EXPECTED_VARIABLES)" ]]; then
|
||||
echo 'Failed to incorporate expected variable values into plan.';
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
terraform apply -auto-approve -backup=- -state-out $STATE_FILE -var-file $TERRAFORM_TFVARS > $APPLY_LOG_FILE 2> $APPLY_ERROR_FILE
|
||||
|
||||
if [[ ! -f $STATE_FILE ]]; then
|
||||
echo "Failed to generate state file - $STATE_FILE";
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# Extract some content the state file.
|
||||
if [[ ! "$(cat $STATE_FILE)" == *'0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517'* ]]; then
|
||||
echo 'Failed to retrieve expected content from AWS.';
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# Extract some content from the apply log.
|
||||
if [[ ! "$(cat $APPLY_LOG_FILE)" == *"0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517"* ]]; then
|
||||
echo 'Failed to present expected content to Terraform.';
|
||||
exit 5;
|
||||
fi
|
||||
|
||||
# Validate the absence of the debug log.
|
||||
if [[ -f $DEBUG_LOG_FILE ]]; then
|
||||
echo "Incorrectly generated debug.log file - $DEBUG_LOG_FILE";
|
||||
exit 6;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
@@ -0,0 +1,4 @@
|
||||
// 65 characters is too long
|
||||
role_session_name = "12345678901234567890123456789012345678901234567890123456789012345"
|
||||
aws_cli_commands = ["version"]
|
||||
debug_log_filename = "test-reports/role_session_name_too_long/debug.log"
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ -f $PLAN_FILE ]]; then
|
||||
echo "Incorrectly generated a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! -z "$(cat $PLAN_LOG_FILE)" ]]; then
|
||||
echo "Incorrectly generated content in the plan log file - $PLAN_LOG_FILE";
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
if [[ ! "$(cat $PLAN_ERROR_FILE)" == *'The role session name must be less than or equal to 64 characters'* ]]; then
|
||||
echo 'Failed to detect too long role_session_name.';
|
||||
exit 3;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"assume_role_arn": {
|
||||
"value": ""
|
||||
},
|
||||
"aws_cli_commands": {
|
||||
"value": [
|
||||
"s3api",
|
||||
"list-objects",
|
||||
"--bucket",
|
||||
"ryft-public-sample-data",
|
||||
"--no-sign-request"
|
||||
]
|
||||
},
|
||||
"aws_cli_query": {
|
||||
"value": "max_by(Contents, &Size)"
|
||||
},
|
||||
"debug_log_filename": {
|
||||
"value": "test-reports/test_with_debug/debug.log"
|
||||
},
|
||||
"role_session_name": {
|
||||
"value": "test_with_debug"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// ryft-public-sample-data is a publicly accessible S3 bucket.
|
||||
aws_cli_commands = ["s3api", "list-objects", "--bucket", "ryft-public-sample-data", "--no-sign-request"]
|
||||
aws_cli_query = "max_by(Contents, &Size)"
|
||||
debug_log_filename = "test-reports/test_with_debug/debug.log"
|
||||
role_session_name = "test_with_debug"
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ ! -f $PLAN_FILE ]]; then
|
||||
echo "Failed to generate a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! "$(terraform show -json $PLAN_FILE | jq -MSr .variables)" == "$(cat $EXPECTED_VARIABLES)" ]]; then
|
||||
echo 'Failed to incorporate expected variable values into plan.';
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
terraform apply -auto-approve -backup=- -state-out $STATE_FILE -var-file $TERRAFORM_TFVARS > $APPLY_LOG_FILE 2> $APPLY_ERROR_FILE
|
||||
|
||||
if [[ ! -f $STATE_FILE ]]; then
|
||||
echo "Failed to generate state file - $STATE_FILE";
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# Extract some content the state file.
|
||||
if [[ ! "$(cat $STATE_FILE)" == *'0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517'* ]]; then
|
||||
echo 'Failed to retrieve expected content from AWS.';
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# Extract some content from the apply log.
|
||||
if [[ ! "$(cat $APPLY_LOG_FILE)" == *"0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517"* ]]; then
|
||||
echo 'Failed to present expected content to Terraform.';
|
||||
exit 5;
|
||||
fi
|
||||
|
||||
# Validate the presence of the debug log.
|
||||
if [[ ! -f $DEBUG_LOG_FILE ]]; then
|
||||
echo "Failed to generate debug.log file - $DEBUG_LOG_FILE";
|
||||
exit 6;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"assume_role_arn": {
|
||||
"value": ""
|
||||
},
|
||||
"aws_cli_commands": {
|
||||
"value": [
|
||||
"s3api",
|
||||
"list-objects",
|
||||
"--bucket",
|
||||
"ryft-public-sample-data",
|
||||
"--no-sign-request"
|
||||
]
|
||||
},
|
||||
"aws_cli_query": {
|
||||
"value": "max_by(Contents, &Size)"
|
||||
},
|
||||
"debug_log_filename": {
|
||||
"value": ""
|
||||
},
|
||||
"role_session_name": {
|
||||
"value": "test_without_debug"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// ryft-public-sample-data is a publicly accessible S3 bucket.
|
||||
aws_cli_commands = ["s3api", "list-objects", "--bucket", "ryft-public-sample-data", "--no-sign-request"]
|
||||
aws_cli_query = "max_by(Contents, &Size)"
|
||||
role_session_name = "test_without_debug"
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function run_test() {
|
||||
if [[ ! -f $PLAN_FILE ]]; then
|
||||
echo "Failed to generate a plan - $PLAN_FILE";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! "$(terraform show -json $PLAN_FILE | jq -MSr .variables)" == "$(cat $EXPECTED_VARIABLES)" ]]; then
|
||||
echo 'Failed to incorporate expected variable values into plan.';
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
terraform apply -auto-approve -backup=- -state-out $STATE_FILE -var-file $TERRAFORM_TFVARS > $APPLY_LOG_FILE 2> $APPLY_ERROR_FILE
|
||||
|
||||
if [[ ! -f $STATE_FILE ]]; then
|
||||
echo "Failed to generate state file - $STATE_FILE";
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# Extract some content the state file.
|
||||
if [[ ! "$(cat $STATE_FILE)" == *'0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517'* ]]; then
|
||||
echo 'Failed to retrieve expected content from AWS.';
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# Extract some content from the apply log.
|
||||
if [[ ! "$(cat $APPLY_LOG_FILE)" == *"0ae8f910a30bc83fd81c4e3c1a6bbd9bab0afe4e0762b56a2807d22fcd77d517"* ]]; then
|
||||
echo 'Failed to present expected content to Terraform.';
|
||||
exit 5;
|
||||
fi
|
||||
|
||||
# Validate the absence of the debug log.
|
||||
if [[ -f $DEBUG_LOG_FILE ]]; then
|
||||
echo "Incorrectly generated debug.log file - $DEBUG_LOG_FILE";
|
||||
exit 6;
|
||||
fi
|
||||
}
|
||||
|
||||
. tests/common.sh $0
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash -e
|
||||
rm -rf temp
|
||||
rm -rf test-reports
|
||||
find . -type f -name test.sh | sort | xargs -L 1 bash
|
||||
@@ -0,0 +1,43 @@
|
||||
variable "assume_role_arn" {
|
||||
description = "The ARN of the role being assumed (optional)"
|
||||
type = string
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = can(regex("^(?:arn:aws(?:-cn|-us-gov|):(?:iam|sts)::[0-9]{12}:.+|)$", var.assume_role_arn))
|
||||
error_message = "The optional ARN must match the format documented in https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html."
|
||||
}
|
||||
}
|
||||
|
||||
variable "aws_cli_commands" {
|
||||
description = "The AWS CLI command and subcommands"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "aws_cli_query" {
|
||||
description = "The --query value"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "role_session_name" {
|
||||
description = "The role session name"
|
||||
type = string
|
||||
default = ""
|
||||
|
||||
validation {
|
||||
condition = length(var.role_session_name) <= 64
|
||||
error_message = "The role session name must be less than or equal to 64 characters."
|
||||
}
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[\\w+=,.@-]*$", var.role_session_name))
|
||||
error_message = "The role session name match the regular expression '^[\\w+=,.@-]*$'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "debug_log_filename" {
|
||||
description = "Generate a debug log if a `debug_log_filename` is supplied"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_version = ">= 0.15"
|
||||
required_providers {
|
||||
external = {
|
||||
source = "hashicorp/external"
|
||||
version = "~> 2.0"
|
||||
}
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = "~> 2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user