High availability
- For high availability, your architecture should include at least two Availability Zones.
- Consider adding load balancers and AWS Auto Scaling to automatically rebalance your nodes across zones.
- For additional details about high availability and disaster recovery, see the AWS Well-Architected Framework whitepaper.
Security
-
Place your product instances in private subnets, and route private subnet traffic through NAT gateways that are configured in public subnets. We recommend this configuration unless your architecture requires otherwise (e.g., your application provides networking services or manages other servers, and therefore requires a direct inbound connection from the internet).
-
Always use security groups and IAM roles to limit access to resources. Provision minimal access by applying the principle of least privilege (PoLP).
-
For bastion host access, provide a CIDR block parameter and apply it as an ingress rule to the bastion security group. In other security groups, add the bastion security group for connectivity within the VPC for administration, if needed. For example, a web server security group could include an ingress rule for the bastion host security group for SSH TCP port 22.
-
Consider integrating Amazon Inspector into the deployment. This should be an opt-in feature, because Amazon Inspector installs agents on each instance, and not all users will want that.
-
Consider supporting multiple ENIs for private channels between nodes.
-
Do not hardcode passwords. Instead, request them as parameters and include the
NoEcho
property. -
Do not pass sensitive data in EC2-instance user data or other clear text bootstrapping mechanisms. If you write secrets to a secured file, you must delete it after stack completion.
-
Do not hardcode security groups to 0.0.0.0/0 for ingress rules.
-
Do not create IAM resources with custom names. Custom names require additional permissions like CAPABILITY_NAMED_IAM, and increase the chances of a collision if the stack is launched concurrently in an account.
-
Scrub logs for passwords, and avoid explicit output (
bash set -x
).
For additional recommendations, see the Introduction to AWS Security whitepaper.
Portability
- Use the Quick Start portability parameters to support extensions and customizations for your Quick Start.
Using AWS-managed services
- Use AWS-managed services, such as Amazon Relational Database Service (Amazon RDS) and AWS Directory Service, whenever possible.
- Use Auto Scaling groups to automatically adjust resource capacity.
- Use load balancers (preferably Application Load Balancing or Elastic Load Balancing) for traffic distribution and to maintain application availability.
Using custom resources
If you’re implementing Lambda-backed custom resources in your CloudFormation stack, review the best practices discussed in the AWS Support Knowledge Center.
Linux
-
Enable the
-e
flag at the top of all scripts (except user data) as follows:#!/bin/bash –e
This will cause the script to exit with a non-zero exit code.
-
Use
$?
to check the status of your user data scripts. - Modularize bootstrap stages:
- Pre-install script examples:
- Enables epel repos
- Checks for
curl
,wget unzip
- Installs rpms or debs
- Set up python setup tools (
pip
/easy_install
) - Creates logical volumes and mount points
- Enables service on boot (using
systemctl
orchkconfig
)
- App environment script examples:
- Configures application writes (``/etc/someapp.conf`)
- Creates MySQL schema
- Updates pip modules
- App install:
- Install core application
- Execute installation with needed assets (license file or location)
- Pre-install script examples:
-
Check status when switching install stage (pre-install/app-env/app-install). Non-zero status is a failed execution. For example:
cat some.sh | bash -e -o pipefail if [ $STATUS -eq 0 ] then echo "Script [PASS]" # Continue to next step else echo "Script [FAILED]" >&2 # Signal your resources exit 1 fi
-
Define script names to new bootstrap version so they can be tested in the same location without overwriting existing assets:
LOCATION={ "Ref": "QuickStartS3URL" }/{ "Ref": "QSS3BucketName" }/{ "Ref": "QSS3KeyPrefix" } wget or curl -O ${LOCATION}/scripts/${FILENAME} chmod 755 ${FILENAME}
- Use
-x
flag so all script output is logged to cloud_init-output.log.
Windows
- Utilize common scripts from the GitHub aws-quickstart/quickstart-microsoft-utilities repository by adding them as submodules.
- If you’re using PowerShell scripts, follow these guidelines:
- Wrap your scripts with a
try/catch
block that sends the exception toWrite-AWSQuickStartException
from the AWS Quick Start PowerShell module. - Include
$ErrorActionPreference = "Stop"
at the top of the scripts to ensure that exceptions are caught. - Include a
Start-Transcript C:\cfn\log\<ScriptName>.txt -Append
to capture all of the logging from the script being executed. - Use the
Write-AWSQuickStartException
cmdlet to signal to AWS CloudFormation, and also to write an Event Viewer error with details about the exception. -
Wrap all PowerShell scripts with
try/catch
blocks to signal exceptions and abort stack:param( [Parameter(Mandatory=$true)] [string]$Parameter1 ) try { $ErrorActionPreference = "Stop" #DO STUFF } catch { $_ | Write-AWSQuickStartException }
- Wrap your scripts with a
- Use the AWS Quick Start PowerShell module to manage signaling and exceptions.
-
Handle reboots by using the
waitAfterCompletion
property of a command in the commands section of acfn-init
configuration set. For example:"b-rename-computer": { "command": { "Fn::Join": [ "", [ "powershell.exe -Command \"C:\\cfn\\scripts\\Rename-Computer.ps1 -Restart -NewName '", { "Ref": "WSFCNode1NetBIOSName" }, "'\"" ] ] }, "waitAfterCompletion": "forever" }
- Divide the cfn-init configuration sets into bootstrapping stages. For example: prep, install or setup, configure, and finalize.
For all platforms
- Derive AWS CloudFormation paths by joining Quick Start inputs. For example, a bucket name and key prefix from a parameter can be passed to a script, and the script can join them to create a path. Do not hardcode script paths.
Template formatting
You can author your AWS CloudFormation template in YAML format. For details, see the AWS CloudFormation Template Formats.
For cross-platform compatibility in either format, use List File (LF) for UNIX-style line endings.
YAML:
- Use 2-space tabs for indentation.
- Wrap strings with single quotes.
GitHub Branches
When creating your Quick Start repository, we suggest you follow the GitHub recommendations on branch names.
Branch names to use:
- main
- develop
If you need to rename your branches follow the instructions at the following link: https://github.com/github/renaming
Note: The Quick Start team is currently in the process of renaming “master” to “main” in all currently published Quick Starts.