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

Watchers

Forks

Releases

No releases published

Packages

No packages published