Skip to content

rgl/terraform-aws-documentdb-example

Repository files navigation

About

Lint

This deploys an example Amazon DocumentDB instance, Amazon API Gateway, and AWS Lambda Function.

This will:

  • Use the Amazon DocumentDB Service.
    • Create a Database instance.
  • Build an example Go AWS Lambda Function as a Container Image.
    • At each request, increment the counters.hits.counter property, and return its modified value.
    • Create the counters database.
    • Create the hits database collection.
    • Get the database credentials from a Secret.
    • Upload it to the Amazon ECR.
  • Create an Amazon API Gateway.
    • Configure it to use the Go AWS Lambda Function.
  • Create a VPC and all the required plumbing required for the Go AWS Lambda Function to use an Amazon DocumentDB Database instance.

Usage (on a Ubuntu Desktop)

Install the dependencies:

Set the AWS Account credentials using SSO, e.g.:

# set the account credentials.
# NB the aws cli stores these at ~/.aws/config.
# NB this is equivalent to manually configuring SSO using aws configure sso.
# see https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html#sso-configure-profile-token-manual
# see https://docs.aws.amazon.com/cli/latest/userguide/sso-configure-profile-token.html#sso-configure-profile-token-auto-sso
cat >secrets.sh <<'EOF'
# set the environment variables to use a specific profile.
# NB use aws configure sso to configure these manually.
# e.g. use the pattern <aws-sso-session>-<aws-account-id>-<aws-role-name>
export aws_sso_session='example'
export aws_sso_start_url='https://example.awsapps.com/start'
export aws_sso_region='eu-west-1'
export aws_sso_account_id='123456'
export aws_sso_role_name='AdministratorAccess'
export AWS_PROFILE="$aws_sso_session-$aws_sso_account_id-$aws_sso_role_name"
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_DEFAULT_REGION
# configure the ~/.aws/config file.
# NB unfortunately, I did not find a way to create the [sso-session] section
#    inside the ~/.aws/config file using the aws cli. so, instead, manage that
#    file using python.
python3 <<'PY_EOF'
import configparser
import os
aws_sso_session = os.getenv('aws_sso_session')
aws_sso_start_url = os.getenv('aws_sso_start_url')
aws_sso_region = os.getenv('aws_sso_region')
aws_sso_account_id = os.getenv('aws_sso_account_id')
aws_sso_role_name = os.getenv('aws_sso_role_name')
aws_profile = os.getenv('AWS_PROFILE')
config = configparser.ConfigParser()
aws_config_directory_path = os.path.expanduser('~/.aws')
aws_config_path = os.path.join(aws_config_directory_path, 'config')
if os.path.exists(aws_config_path):
  config.read(aws_config_path)
config[f'sso-session {aws_sso_session}'] = {
  'sso_start_url': aws_sso_start_url,
  'sso_region': aws_sso_region,
  'sso_registration_scopes': 'sso:account:access',
}
config[f'profile {aws_profile}'] = {
  'sso_session': aws_sso_session,
  'sso_account_id': aws_sso_account_id,
  'sso_role_name': aws_sso_role_name,
  'region': aws_sso_region,
}
os.makedirs(aws_config_directory_path, mode=0o700, exist_ok=True)
with open(aws_config_path, 'w') as f:
  config.write(f)
PY_EOF
unset aws_sso_start_url
unset aws_sso_region
unset aws_sso_session
unset aws_sso_account_id
unset aws_sso_role_name
# show the user, user amazon resource name (arn), and the account id, of the
# profile set in the AWS_PROFILE environment variable.
if ! aws sts get-caller-identity >/dev/null 2>&1; then
  aws sso login
fi
aws sts get-caller-identity
EOF

Or, set the AWS Account credentials using an Access Key, e.g.:

# set the account credentials.
# NB get these from your aws account iam console.
#    see Managing access keys (console) at
#        https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey
cat >secrets.sh <<'EOF'
export AWS_ACCESS_KEY_ID='TODO'
export AWS_SECRET_ACCESS_KEY='TODO'
unset AWS_PROFILE
# set the default region.
export AWS_DEFAULT_REGION='eu-west-1'
# show the user, user amazon resource name (arn), and the account id.
aws sts get-caller-identity
EOF

Review the inputs.tf file.

Initialize the project:

terraform init -lockfile=readonly

Deploy the example:

export CHECKPOINT_DISABLE='1'
export TF_LOG='DEBUG' # TRACE, DEBUG, INFO, WARN or ERROR.
export TF_LOG_PATH='terraform.log'
rm -f "$TF_LOG_PATH"
terraform apply

Show the terraform state:

terraform state list
terraform show

Access the example service (hosted by the Go AWS Lambda Function Container):

example_url="$(terraform output --raw example_url)"
curl \
  -s \
  -X GET \
  "$example_url" \
  | jq

You should see a response alike the following, where the hitsCounter property value is incremented after each request:

{
  "hitsCounter": 1
}

Test recreating the lambda function:

terraform destroy -target=module.example_lambda_function
terraform apply

Destroy the example:

terraform destroy

List this repository dependencies (and which have newer versions):

GITHUB_COM_TOKEN='YOUR_GITHUB_PERSONAL_TOKEN' ./renovate.sh

Notes

  • There is no way to use an AWS IAM Role to authenticate as a DocumentDB User.
    • This means we cannot use the Lambda Function IAM Role as a password-less authentication mechanism. So, we must manage the DocumentDB User password.

About

An example Amazon DocumentDB instance, Amazon API Gateway, and AWS Lambda Function

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors