This project serves as a location for samples implementing AWS services with documentation as to the function of various services, configurations, pipelines, and IAC for onboarding to Amazon Web Services.
Using these directions will set up various AWS services, some of which will incur charges. Be aware of this
before deploying services, and be sure to tear down services that are no longer being used with terraform destroy
(explained in more detail later) to minimize unnecessary costs.
Follow the directions here to set up your initial AWS Account.
Terraform is our Infrastructure as Code (IAC) tool. The primary function of Terraform and other IAC platforms is to compare a declared and desired configuration against the actual state of the impacted resources in the cloud and automatically determine sets of changes needed to reach the intended state as defined in the configuration files (for Terraform, this is in YAML).It exists in a family of tools that also includes:
This project will not include a discussion of the merits/drawbacks of each - we will use Terraform for all IAC.
NOTE: Deploying changes in Terraform and is performed with the command terraform apply
.
Terraform will show a list of the changes to be made, and the user can specify whether or no to proceed. Type yes
to apply the changes. These steps apply to all Terraform modules described below.
To install Terraform on Windows:
- Install Chocolatey
- Install Terraform via Chocolatey using the commands for
Chocolatey on Windows
here
To install Terraform on macOS:
The AWS CLI allows developers to interact with AWS services directly using various command line interactions. While our interactions with AWS will be primarily performed via Terraform, for Terraform to interact with AWS the user must have an active session established and authenticated. The AWS CLI will allow us to establish this session.
Follow the directions here to install the AWS CLI on Windows or macOS.
Once the AWS CLI is installed, the developer will need to authenticate to AWS using their IAM user. The best way to do this is with Single Sign On (SSO). To do this, open a terminal and then:
- Enter the command
aws configure sso
- Provide the
SSO session name
(suggest first initial last name dash dev, exampletparikka-dev
) - Provide the
SSO start URL
found in theAWS Access Portal
in theAccess Keys
section under the account / user dropdown - Provide the
SSO region
(suggest the AWS region where development will happen, this repo usesus-east-1
) - Leave
SSO registration scopes
default - The terminal will open your browser and ask you to confirm the 8 char code in the browser and your terminal match.
If they do, click
Confirm and Continue
and thenAllow Access
- Set the
CLI default client
to the same as yourSSO region
- Leave the
CLI default output format
default - Either accept the default
CLI profile name
or set a new one, but be sure to note the profile name for future use
At this point, your terminal is authenticated and the session can be used by Terraform.
Setting the AWS_PROFILE environment variable will allow Terraform to use that profile across the board for all interactions without requiring source code changes:
- At a Powershell terminal, use the command
$env:AWS_PROFILE=myprofilename
, substituting the profile name specified at the last step ofLog In With AWS SSO
- At a zsh or Bash terminal, use the command
EXPORT AWS_PROFILE=myprofilename
, substituting the profile name specified at the last step ofLog In With AWS SSO
In order to prevent multiple users from applying conflicting changes at the same time and to improve collaboration, it is common to store both lock state (which prevents collisions) and current system state in a cloud resource of some kind. In AWS, the lock state is stored in DynamoDB (a NoSQL database) and the system state is stored in S3 (a file storage service). If these are not stored in the cloud, they must be instead stored locally on a developer's laptop which is suboptimal.
For this to work the DynamoDB table and S3 storage bucket must exist, creating a "chicken and egg" situation. We address
this by creating a "landing zone" Terraform module that establishes the minimum possible assets required to support
IAC deployments. This module can be lives in /iac/landing-zone
.
NOTE: Because S3 bucket names must be globally unique, in s3.tf
the bucket name must be updated. Replace
firstname-lastname
with the developer's first and last name to provide uniqueness. There is also a provider.tf
in
each other module where the bucket
name in the backend
section must be updated to reflect this value in the
developer's fork.
Once the landing zone has been deployed, other infrastructure can be deployed as needed. This can include resources like:
In this example, the only component at the infra level is a federated connection allowing GitHub / AWS interactions. This allows GitHub Actions to perform actions like deploying services and container images to AWS. The repo includes defaults based on the maintainer's environment that can be overridden at Terraform runtime like so:
terraform apply -var="account_id=123456789" -var="github_repository=yourname/yourreponame" -var="idp_thumbprint=asdf"
Alternately, if the repo is forked the user can replace the default with their own value. The variables can also be supplied as part of a deployment pipeline, which is outside the current scope of this sample.
Related Links:
The following sample systems are available for testing. They are system level modules that rely on the previously described modules. They have their own README.md files. They include:
See the specific READMEs for the components for usage instructions.
When tearing down sample systems, do so in this order:
- The
sample-ecr
repository - Each other main "Sample System" that has been created, any order
- The
infrastructure
module - The
landing-zone
module
Note that force-destroy
is enabled on the S3 state bucket in the landing zone to allow for an instant delete
operation for demos. This is not recommended for a production bucket.