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.
- The Secret is stored in AWS Secrets Manager.
- Upload it to the Amazon ECR.
- At each request, increment the
- 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.
- Make the Document DB Database instance available in a VPC database subnet.
- Make the Secrets Manager service endpoint available as a VPC Endpoint.
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
- 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.