source/infrastructure/deploy-core-single-stack.bash (314 lines of code) (raw):
#!/bin/bash
set -e
if [[ "$DEBUG" == "true" ]]; then
set -x
fi
function help_message {
cat << EOF
NAME
deploy-core.bash
DESCRIPTION
Deploys the CDF core services.
MANDATORY ARGUMENTS:
-e (string) Name of environment.
-c (string) Location of infrastructure project containing CDF application configuration.
-b (string) The name of the S3 bucket to deploy CloudFormation templates and configuration into.
-y (string) S3 uri base directory where Cloudformation template snippets are stored.
OPTIONAL ARGUMENTS
COMMON OPTIONS::
----------------
-E (string) Name of configuration environment. If not provided, then '-e ENVIRONMENT' is used.
-k (string) The KMS Key id that the provisioning service will use to decrypt sensitive information. If not provided, a new KMS key with the alias 'cdf' is created.
-z (string) Name of API Gateway cloudformation template snippet. If none provided, all API Gateway instances are configured without authentication.
COMMON AUTH OPTIONS::
-------------------------------
-a (string) API Gateway authorization type. Must be from the following list (default is None):
- None
- Private
- Cognito
- LambdaRequest
- LambdaToken
- ApiKey
- IAM
COMMON PRIVATE API AUTH OPTIONS, OR ASSET LIBRARY (FULL) MODE::
-------------------------------------------------------------------
-N (flag) Use an existing VPC instead of creating a new one.
-v (string) ID of VPC to deploy into (required if -N set)
-g (string) ID of CDF security group (required if -N set)
-n (string) ID of private subnets (comma delimited) (required if -N set)
-o (string) ID of public subnets (comma delimited) (required if -N set)
-I (string) ID of VPC endpoint (required if -N set)
-r (string) ID of private route tables (comma delimited) (required if -N set)
COMMON COGNITO AUTH OPTIONS:
--------------------------
-C (string) Cognito user pool arn
COMMON LAMBDA REQUEST/TOKEN AUTH OPTIONS:
---------------------------------------------
-A (string) Lambda authorizer function arn.
ASSET LIBRARY OPTIONS::
-----------------------
-m (string) Asset Library mode ('full' or 'lite'). Defaults to full if not provided.
-p (string) The name of the key pair to use to deploy the Bastion EC2 host (required for Asset Library (full) mode or Private auth mode).
-i (string) The remote access CIDR to configure Bastion SSH access (e.g. 1.2.3.4/32) (required for Asset Library (full) mode).
-u (string) The Neptune DB Instance type. Default is db.r5.xlarge but may change in future. Refer to https://aws.amazon.com/neptune/pricing/ for a list of instance types available in your region.
COMPILING OPTIONS:
------------------
-B (flag) Bypass bundling each module. If deploying from a prebuilt tarfile rather than source code, setting this flag will speed up the deploy.
-Y (flag) Proceed with install bypassing the prompt requesting permission continue.
AWS OPTIONS:
------------
-R (string) AWS region.
-P (string) AWS profile.
DEPENDENCIES REQUIRED:
- aws-cli
- jq
- zip
- git
- pnpm
EOF
}
#-------------------------------------------------------------------------------
# Validate all COMMON arguments. Any SERVICE specific arguments are validated
# by the service specific deployment script.
#-------------------------------------------------------------------------------
while getopts ":e:E:p:i:k:K:I:b:c:a:u:y:z:C:A:Nv:g:n:m:o:r:BYR:P:" opt; do
case $opt in
e ) ENVIRONMENT=$OPTARG;;
E ) CONFIG_ENVIRONMENT=$OPTARG;;
p ) BASTION_KEYPAIR_NAME=$OPTARG;;
i ) BASTION_REMOTE_ACCESS_CIDR=$OPTARG;;
k ) KMS_KEY_ID=$OPTARG;;
b ) ARTIFACTS_BUCKET=$OPTARG;;
m ) ASSETLIBRARY_MODE=$OPTARG;;
c ) CDF_INFRA_CONFIG=$OPTARG;;
u ) NEPTUNE_INSTANCE_TYPE=$OPTARG;;
a ) API_GATEWAY_AUTH=$OPTARG;;
y ) TEMPLATE_SNIPPET_S3_URI_BASE=$OPTARG;;
z ) API_GATEWAY_DEFINITION_TEMPLATE=$OPTARG;;
C ) COGNTIO_USER_POOL_ARN=$OPTARG;;
A ) AUTHORIZER_FUNCTION_ARN=$OPTARG;;
N ) USE_EXISTING_VPC=true;;
v ) VPC_ID=$OPTARG;;
g ) CDF_SECURITY_GROUP_ID=$OPTARG;;
n ) PRIVATE_SUBNET_IDS=$OPTARG;;
o ) PUBLIC_SUBNET_IDS=$OPTARG;;
r ) PRIVATE_ROUTE_TABLE_IDS=$OPTARG;;
I ) PRIVATE_ENDPOINT_ID=$OPTARG;;
B ) BYPASS_BUNDLE=true;;
Y ) BYPASS_PROMPT=true;;
R ) AWS_REGION=$OPTARG;;
P ) AWS_PROFILE=$OPTARG;;
\? ) echo "Unknown option: -$OPTARG" >&2; help_message; exit 1;;
: ) echo "Missing option argument for -$OPTARG" >&2; help_message; exit 1;;
* ) echo "Unimplemented option: -$OPTARG" >&2; help_message; exit 1;;
esac
done
cwd=$(dirname "$0")
root_dir=$(pwd)
# path is from aws-connected-device-framework root
source $cwd/common-deploy-functions.bash
incorrect_args=0
DEPLOY_PARAMETERS=()
incorrect_args=$((incorrect_args+$(verifyMandatoryArgument ENVIRONMENT e $ENVIRONMENT)))
CONFIG_ENVIRONMENT="$(defaultIfNotSet 'CONFIG_ENVIRONMENT' E ${CONFIG_ENVIRONMENT} ${ENVIRONMENT})"
API_GATEWAY_AUTH="$(defaultIfNotSet 'API_GATEWAY_AUTH' a ${API_GATEWAY_AUTH} 'None')"
incorrect_args=$((incorrect_args+$(verifyApiGatewayAuthType $API_GATEWAY_AUTH)))
if [[ "$API_GATEWAY_AUTH" = "Cognito" ]]; then
incorrect_args=$((incorrect_args+$(verifyMandatoryArgument COGNTIO_USER_POOL_ARN C $COGNTIO_USER_POOL_ARN)))
fi
if [[ "$API_GATEWAY_AUTH" = "LambdaRequest" || "$API_GATEWAY_AUTH" = "LambdaToken" ]]; then
incorrect_args=$((incorrect_args+$(verifyMandatoryArgument AUTHORIZER_FUNCTION_ARN A $AUTHORIZER_FUNCTION_ARN)))
fi
incorrect_args=$((incorrect_args+$(verifyMandatoryArgument ARTIFACTS_BUCKET b "$ARTIFACTS_BUCKET")))
incorrect_args=$((incorrect_args+$(verifyMandatoryArgument TEMPLATE_SNIPPET_S3_URI_BASE y "$TEMPLATE_SNIPPET_S3_URI_BASE")))
API_GATEWAY_DEFINITION_TEMPLATE="$(defaultIfNotSet 'API_GATEWAY_DEFINITION_TEMPLATE' z ${API_GATEWAY_DEFINITION_TEMPLATE} 'cfn-apiGateway-noAuth.yaml')"
ASSETLIBRARY_MODE="$(defaultIfNotSet 'ASSETLIBRARY_MODE' m ${ASSETLIBRARY_MODE} 'full')"
NEPTUNE_INSTANCE_TYPE="$(defaultIfNotSet 'NEPTUNE_INSTANCE_TYPE' m ${NEPTUNE_INSTANCE_TYPE} 'db.r5.xlarge')"
BASTION_REMOTE_ACCESS_CIDR="$(defaultIfNotSet 'BASTION_REMOTE_ACCESS_CIDR' i ${BASTION_REMOTE_ACCESS_CIDR} '0.0.0.0/0')"
DEPLOY_PARAMETERS+=( Environment=$ENVIRONMENT )
DEPLOY_PARAMETERS+=( ArtifactsBucket=$ARTIFACTS_BUCKET )
DEPLOY_PARAMETERS+=( TemplateSnippetS3UriBase=$TEMPLATE_SNIPPET_S3_URI_BASE )
DEPLOY_PARAMETERS+=( AuthType=$API_GATEWAY_AUTH )
DEPLOY_PARAMETERS+=( ApiGatewayDefinitionTemplate=$API_GATEWAY_DEFINITION_TEMPLATE )
DEPLOY_PARAMETERS+=( CognitoUserPoolArn=$COGNTIO_USER_POOL_ARN )
DEPLOY_PARAMETERS+=( AuthorizerFunctionArn=$AUTHORIZER_FUNCTION_ARN )
DEPLOY_PARAMETERS+=( BastionKeyPairName=$BASTION_KEYPAIR_NAME )
DEPLOY_PARAMETERS+=( BastionRemoteAccessCIDR=$BASTION_REMOTE_ACCESS_CIDR )
if [ ! -z "$CDF_INFRA_CONFIG" ] || [ "$CDF_INFRA_CONFIG" != "" ]; then
if [ -f "$CDF_INFRA_CONFIG/assetlibrary/$CONFIG_ENVIRONMENT-config.json" ]; then
assetlibrary_config=$(cat $CDF_INFRA_CONFIG/assetlibrary/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( AssetLibraryAppConfigOverride="$assetlibrary_config" )
else
DEPLOY_PARAMETERS+=( IncludeAssetLibrary=false )
fi
if [ -f "$CDF_INFRA_CONFIG/assetlibrary-export/$CONFIG_ENVIRONMENT-config.json" ]; then
assetlibrary_export_config=$(cat $CDF_INFRA_CONFIG/assetlibrary-export/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( AssetLibraryExportAppConfigOverride="$assetlibrary_export_config" )
else
DEPLOY_PARAMETERS+=( IncludeAssetLibraryExport=false )
fi
if [ -f "$CDF_INFRA_CONFIG/assetlibraryhistory/$CONFIG_ENVIRONMENT-config.json" ]; then
assetlibrary_history_config=$(cat $CDF_INFRA_CONFIG/assetlibraryhistory/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( AssetLibraryHistoryAppConfigOverride="$assetlibrary_history_config" )
else
DEPLOY_PARAMETERS+=( IncludeAssetLibraryHistory=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/commands/$CONFIG_ENVIRONMENT-config.json" ]]; then
commands_config=$(cat $CDF_INFRA_CONFIG/commands/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( CommandsAppConfigOverride="$commands_config" )
else
DEPLOY_PARAMETERS+=( IncludeCommands=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/provisioning/$CONFIG_ENVIRONMENT-config.json" ]]; then
provisioning_config=$(cat $CDF_INFRA_CONFIG/provisioning/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( ProvisioningAppConfigOverride="$provisioning_config" )
else
DEPLOY_PARAMETERS+=( IncludeProvisioning=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/bulkcerts/$CONFIG_ENVIRONMENT-config.json" ]]; then
bulkcerts_config=$(cat $CDF_INFRA_CONFIG/bulkcerts/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( BulkCertsAppConfigOverride="$bulkcerts_config" )
else
DEPLOY_PARAMETERS+=( IncludeBulkCerts=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/devicemonitoring/$CONFIG_ENVIRONMENT-config.json" ]]; then
devicemonitoring_config=$(cat $CDF_INFRA_CONFIG/devicemonitoring/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( DeviceMonitoringAppConfigOverride="$devicemonitoring_config" )
else
DEPLOY_PARAMETERS+=(IncludeDeviceMonitoring=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/simulation-manager/$CONFIG_ENVIRONMENT-config.json" ]]; then
simulation_manager_config=$(cat $CDF_INFRA_CONFIG/simulation-manager/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( SimulationManagerAppConfigOverride="$simulation_manager_config" )
else
DEPLOY_PARAMETERS+=( IncludeSimulationManager=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/simulation-launcher/$CONFIG_ENVIRONMENT-config.json" ]]; then
simulation_launcher_config=$(cat $CDF_INFRA_CONFIG/simulation-launcher/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( SimulationLauncherAppConfigOverride="$simulation_launcher_config" )
else
DEPLOY_PARAMETERS+=( IncludeSimulationLauncher=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/certificatevendor/$CONFIG_ENVIRONMENT-config.json" ]]; then
certificate_vendor_config=$(cat $CDF_INFRA_CONFIG/certificatevendor/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( CertificateVendorAppConfigOverride="$certificate_vendor_config" )
else
DEPLOY_PARAMETERS+=( IncludeCertificateVendor=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/certificateactivator/$CONFIG_ENVIRONMENT-config.json" ]]; then
certificate_activator_config=$(cat $CDF_INFRA_CONFIG/certificateactivator/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( CertificateActivatorAppConfigOverride="$certificate_activator_config" )
else
DEPLOY_PARAMETERS+=( IncludeCertificateActivator=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/events-processor/$CONFIG_ENVIRONMENT-config.json" ]]; then
events_processor_config=$(cat $CDF_INFRA_CONFIG/events-processor/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( EventsProcessorAppConfigOverride="$events_processor_config" )
else
DEPLOY_PARAMETERS+=( IncludeEventProcessor=false )
fi
if [[ -f "$CDF_INFRA_CONFIG/events-alerts/$CONFIG_ENVIRONMENT-config.json" ]]; then
events_alerts_config=$(cat $CDF_INFRA_CONFIG/events-alerts/$CONFIG_ENVIRONMENT-config.json)
DEPLOY_PARAMETERS+=( EventsAlertsAppConfigOverride="$events_alerts_config" )
else
DEPLOY_PARAMETERS+=( IncludeEventAlerts=false )
fi
fi
if [ "$ASSETLIBRARY_MODE" = "full" ]; then
if [ -z "$BASTION_KEYPAIR_NAME" ]; then
echo "ERROR: Deploying AssetLibrary in Full mode; EC2 Keypair Name must be provided"
help_message; exit 1;
fi
fi
# if provided, use existing kms
DEPLOY_PARAMETERS+=( KmsKeyId=$KMS_KEY_ID )
if [ -n "$USE_EXISTING_VPC" ] && [ "$USE_EXISTING_VPC" = 'true' ]; then
# if private api auth, or asset library full mode, is configured then these will get overwritten
DEPLOY_PARAMETERS+=( ExistingVpcId=$VPC_ID )
DEPLOY_PARAMETERS+=( ExistingCDFSecurityGroupId=$CDF_SECURITY_GROUP_ID )
DEPLOY_PARAMETERS+=( ExistingPrivateSubnetIds=$PRIVATE_SUBNET_IDS )
DEPLOY_PARAMETERS+=( ExistingPublicSubnetIds=$PUBLIC_SUBNET_IDS )
DEPLOY_PARAMETERS+=( ExistingPrivateApiGatewayVPCEndpoint=$PRIVATE_ENDPOINT_ID )
DEPLOY_PARAMETERS+=( ExistingPrivateRouteTableIds=$PRIVATE_ROUTE_TABLE_IDS )
fi
if [ -n "$NEPTUNE_INSTANCE_TYPE" ]; then
DEPLOY_PARAMETERS+=( NeptuneDbInstanceType=$NEPTUNE_INSTANCE_TYPE )
fi
if [[ "incorrect_args" -gt 0 ]]; then
help_message; exit 1;
fi
if [ -z "$AWS_REGION" ]; then
AWS_REGION=$(aws configure get region $AWS_ARGS)
fi
AWS_ARGS=$(buildAwsArgs "$AWS_REGION" "$AWS_PROFILE" )
AWS_SCRIPT_ARGS=$(buildAwsScriptArgs "$AWS_REGION" "$AWS_PROFILE" )
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account' $AWS_ARGS)
##########################################################
###### confirm whether to proceed or not ######
##########################################################
config_message="
**********************************************************
***** AWS Connected Device Framework Core Config ******
**********************************************************
The AWS Connected Device Framework (CDF) will install using the following configuration:
-e (ENVIRONMENT) : $ENVIRONMENT
-E (CONFIG_ENVIRONMENT) : $CONFIG_ENVIRONMENT
-d (INFRASTRUCTURE_CONFIGURATION) : $CDF_INFRA_CONFIG"
if [[ -z "$CDF_INFRA_CONFIG" ]]; then
config_message+='not provided, therefore deploying all microservices'
fi
config_message+="
-y (TEMPLATE_SNIPPET_S3_URI_BASE) : $TEMPLATE_SNIPPET_S3_URI_BASE
-z (API_GATEWAY_DEFINITION_TEMPLATE) : $API_GATEWAY_DEFINITION_TEMPLATE
-a (API_GATEWAY_AUTH) : $API_GATEWAY_AUTH
-C (COGNTIO_USER_POOL_ARN) : $COGNTIO_USER_POOL_ARN
-A (AUTHORIZER_FUNCTION_ARN) : $AUTHORIZER_FUNCTION_ARN
-b (ARTIFACTS_BUCKET) : $ARTIFACTS_BUCKET
-p (BASTION_KEYPAIR_NAME) : $BASTION_KEYPAIR_NAME
-k (KMS_KEY_ID) : $KMS_KEY_ID
-m (ASSETLIBRARY_MODE) : $ASSETLIBRARY_MODE
-i (BASTION_REMOTE_ACCESS_CIDR) : $BASTION_REMOTE_ACCESS_CIDR
-u (NEPTUNE_INSTANCE_TYPE) : $NEPTUNE_INSTANCE_TYPE
-N (USE_EXISTING_VPC) : $USE_EXISTING_VPC"
if [[ -z "$USE_EXISTING_VPC" ]]; then
config_message+='not provided, therefore a new vpc will be created'
else
config_message+="
-v (VPC_ID) : $VPC_ID
-g (CDF_SECURITY_GROUP_ID) : $CDF_SECURITY_GROUP_ID
-n (PRIVATE_SUBNET_IDS) : $PRIVATE_SUBNET_IDS
-o (PUBLIC_SUBNET_IDS) : $PUBLIC_SUBNET_IDS
-I (PRIVATE_ENDPOINT_ID) : $PRIVATE_ENDPOINT_ID
-r (PRIVATE_ROUTE_TABLE_IDS) : $PRIVATE_ROUTE_TABLE_IDS"
fi
config_message+="
-R (AWS_REGION) : $AWS_REGION
-P (AWS_PROFILE) : $AWS_PROFILE
AWS_ACCOUNT_ID : $AWS_ACCOUNT_ID
-B (BYPASS_BUNDLE) : $BYPASS_BUNDLE"
if [ "$BYPASS_BUNDLE" != "true" ]; then
config_message+='not provided, therefore each TypeScript project will be bundled'
fi
asksure "$config_message" $BYPASS_PROMPT
if [ "$BYPASS_BUNDLE" != "true" ]; then
logTitle 'Bundling applications'
rush bundle
fi
mkdir -p $cwd/build
logTitle 'Packaging the aws-connected-device-framework CloudFormation template and uploading to S3'
aws cloudformation package \
--template-file $cwd/cfn-cdf-core-single-stack.yaml \
--output-template-file $cwd/build/cfn-cdf-core-single-stack-output.yaml \
--s3-bucket $ARTIFACTS_BUCKET \
--s3-prefix packaged-cfn-artifacts \
$AWS_ARGS
#### Upload the simulation launcher docker container ####
logTitle 'Deploying Simulation Launcher JMeter Container'
repositoryName="cdf-jmeter-$ENVIRONMENT"
cd "$root_dir/packages/services/simulation-launcher/src/containers/jmeter/infrastructure"
./deploy.bash -b -n $repositoryName $AWS_SCRIPT_ARGS
cd -
DEPLOY_PARAMETERS+=( JMeterRepoName=$repositoryName )
logTitle 'Uploading Cloudformation template snippets'
for snippet in $(ls $cwd/cloudformation/snippets/*); do
key="$TEMPLATE_SNIPPET_S3_URI_BASE"$(basename "$snippet")
aws s3 cp "$snippet" "$key" $AWS_ARGS
done
stack_name="cdf-core-$ENVIRONMENT"
echo "DEPLOY PARAMETERS:"
printf "%s\n" "${DEPLOY_PARAMETERS[@]}"
aws cloudformation deploy \
--stack-name $stack_name \
--template-file "$cwd/build/cfn-cdf-core-single-stack-output.yaml" \
--parameter-overrides "${DEPLOY_PARAMETERS[@]}" \
--capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND \
$AWS_ARGS
logTitle 'CDF deployment complete!'