#!/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!'