Repository navigation
02. Prerequisites
Everything you need before running
terraform applyfor the first time. These five steps are one-time per AWS account.
| At a glance | |
|---|---|
| Setup time | ~15-30 min on a fresh AWS account |
| Repeat on redeploy? | No. Every step here is one-time per AWS account. |
| Marketplace requirement | Kali Linux AMI only (Step 5). All other AMIs are standard AWS with no Marketplace gate. |
| Already set up? | Skip to Deploying Terraform |
- AWS account (a dedicated, isolated account is strongly recommended)
- AWS CLI installed and configured
- Terraform >= 1.0 installed
- Your public IP(s) recorded
- Repository cloned
- SSH key pair created in AWS EC2
- Kali Linux AMI subscribed in AWS Marketplace
git clone https://github.com/BaddKharma/redStack.git
cd redStackInstall AWS CLI:
| Platform | Command |
|---|---|
| macOS | brew install awscli |
| Linux (Ubuntu/Debian) | sudo apt install awscli |
| Linux (any) | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install |
| Windows | Download and run the MSI from https://aws.amazon.com/cli/ |
Install Terraform:
| Platform | Command |
|---|---|
| macOS |
brew tap hashicorp/tap then brew install hashicorp/tap/terraform
|
| Linux (Ubuntu/Debian) | See https://developer.hashicorp.com/terraform/install |
| Windows |
choco install terraform or download from https://developer.hashicorp.com/terraform/install
|
[!NOTE] On macOS,
brew install terraformno longer works, HashiCorp is not in homebrew-core. Use the HashiCorp tap as shown above. During install, agit-credential-osxkeychainpopup may ask for your system password; enter it and click Always Allow (not just Allow) to keep it from looping.
✅ Checkpoint: Repository cloned, AWS CLI and Terraform installed.
Note
Run SSH key commands (Step 4) from inside the redStack/ directory: the key will land here. Terraform commands (Step 5 onward) run from redStack/terraform/ (to protect the tf state files from accidental changes or deletions).
Tip
Use a dedicated AWS account. This is the cleanest model. Create a new free AWS account solely for this lab. Five-minute signup, billing isolated, no risk to your other workloads if a credential leaks.
redStack provisions EC2, VPC, security group, Elastic IP, network interface, and key pair resources. Your AWS credentials need permissions for all of these.
This is the right choice for most redStack users.
If you followed the dedicated-account recommendation, AdministratorAccess is the practical default. There are no other workloads, billing resources, or sensitive data in the account to protect. On an empty account, admin access carries the same real-world risk as a scoped policy. If the credentials are compromised, the attacker can only touch the lab infrastructure you already plan to tear down.
How to create the IAM user and attach AdministratorAccess (click to expand)
Step 1: IAM Console > Users > Create user
Step 2: Username - redS-operator
Step 3: Permissions > Attach policies directly > search "AdministratorAccess"
Step 4: Check AdministratorAccess > Next > Create user
Step 5: Open the new user > Security credentials > Create access key
Step 6: Select - Command Line Interface (CLI) > acknowledge > Next
Step 7: Copy the Access Key ID and Secret Access Key (the secret is shown only once)Use this option only if the account contains workloads, active resources, or anything you can't afford to lose. The policy below grants ec2:* for all Terraform operations, sts:GetCallerIdentity for credential verification, and four read-only IAM actions scoped to your own user.
How to create the IAM user and attach the least-privilege policy (click to expand)
Step 1: IAM Console > Users > Create user
Step 2: Username - redS-operator
Step 3: Permissions > Attach policies directly > Create policy
Step 4: Select the JSON tab and paste the policy shown below
Step 5: Name the policy - redStack-least-privilege > Create policy
Step 6: Back on the user creation screen, search for and attach redStack-least-privilege
Step 7: Next > Create user
Step 8: Open the new user > Security credentials > Create access key
Step 9: Select - Command Line Interface (CLI) > acknowledge > Next
Step 10: Copy the Access Key ID and Secret Access Key (the secret is shown only once)Minimum IAM Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*",
"sts:GetCallerIdentity"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:GetUser",
"iam:GetUserPolicy",
"iam:ListUserPolicies",
"iam:ListAttachedUserPolicies"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
}
]
}[!NOTE] If this machine already has AWS credentials,
aws configureoverwrites the default profile. Clear the old identity or use a named profile before continuing.
Have an identity you no longer need? Clear it first:
rm -rf ~/.aws/
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILEWant to keep it? Configure a dedicated redstack profile (this prompts you for the keys, region, and output, same as below):
aws configure --profile redstackThen point Terraform and the AWS CLI at it. Terraform reads the profile from AWS_PROFILE and has no --profile flag, so either export it for the session:
export AWS_PROFILE=redstackThat persists until you close the shell. To use it for a single command instead, prepend it:
AWS_PROFILE=redstack terraform planOtherwise (clean machine, or after clearing above), configure the default profile:
aws configureAWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPOxFiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json
What each prompt is asking for (click to expand)
- AWS Access Key ID: From IAM > your user > Security credentials. Identifies who is making requests.
- AWS Secret Access Key: Shown once at key creation time. Pairs with the Access Key ID. If you didn't save it, delete and recreate.
-
Default region name: Where redStack deploys. Use
us-east-1unless you have a reason to pick another. Must matchaws_regioninterraform.tfvars. -
Default output format: Use
json. Terraform doesn't use this but it makes CLI output readable when troubleshooting.
✅ Checkpoint: IAM user created and AWS CLI configured with the new credentials.
Note
Why these permissions: ec2:* covers every Terraform-managed resource (instances, VPCs, subnets, SGs, ENIs, EIPs, peering). sts:GetCallerIdentity lets Terraform verify credentials at init. The four iam:* read actions are scoped to your own user so you can debug access-denied errors. No write access to anything outside EC2.
# Check AWS access
aws sts get-caller-identity
# Check Terraform
terraform --version
# Get your public IP
# If this returns an IPv6 address (contains colons), force IPv4 with: curl -4 -s ifconfig.me
# Every localPub_ip entry must be an IPv4 /32; the security groups do not wire up IPv6.
# Run this from each network you deploy from (home, office, hotspot) and record them all.
curl -4 -s ifconfig.meExpected results:
- ✅ AWS CLI returns your account details (Account, Arn, UserId)
- ✅ Terraform version 1.0 or higher
- ✅ Public IP address displayed
[!TIP]
localPub_ipaccepts a list, so you are not limited to one address. If you deploy from more than one network (home, office, phone hotspot), run the command above from each of them and record every result. All of them can be allowlisted in the same deploy. See Deploying Terraform.
✅ Checkpoint: AWS CLI and Terraform working, public IP(s) noted.
Important
Terraform does NOT create the SSH key pair. You create it manually first; Terraform references it by name.
Run the following from inside the redStack/ directory.
Windows (PowerShell)
aws ec2 create-key-pair --key-name rs-rsa-key --query 'KeyMaterial' --output text | Out-File -Encoding ascii rs-rsa-key.pem
icacls "rs-rsa-key.pem" /inheritance:r /grant:r "$($env:USERNAME):R"Linux / macOS (bash)
aws ec2 create-key-pair --key-name rs-rsa-key --query 'KeyMaterial' --output text > ./rs-rsa-key.pem
chmod 400 ./rs-rsa-key.pemVerify the key exists:
aws ec2 describe-key-pairs --key-names rs-rsa-key✅ Checkpoint: SSH key pair created and .pem file saved in the project folder.
Important
Keep rs-rsa-key.pem in the redStack/ root (next to terraform/), not inside terraform/. Terraform runs from redStack/terraform/, so in terraform.tfvars the path is ssh_private_key_path = "../rs-rsa-key.pem" (with ../). The ./rs-rsa-key.pem form points at a nonexistent file and silently breaks the Windows Administrator password decrypt. See Deploying Terraform.
Note
You can also create the key in the AWS Console under EC2 > Key Pairs > Create key pair. Use RSA and .pem format. Download the file into your redStack/ directory and fix permissions with the platform-appropriate command above.
Caution
First-time terraform apply will fail with OptInRequired if this is skipped.
redStack provisions an official Kali Linux operator workstation alongside the C2 lab. Kali AMIs are publicly shared by the Kali project on AWS Marketplace at no charge, but AWS requires a one-time EULA acceptance per account.
- Visit https://aws.amazon.com/marketplace/pp/prodview-fznsw3f7mq7to while signed in to the same AWS account you configured the AWS CLI with.
- Click Continue to Subscribe.
- Click Accept Terms. The page will show "Subscribed" within ~30 seconds.
You don't need to launch anything from the Marketplace UI; Terraform picks up the AMI automatically. Acceptance is permanent for the life of the account.
✅ Checkpoint: Kali Linux AMI subscribed.
Note
If terraform apply failed with OptInRequired before you got here, complete the subscription above and re-run terraform apply. No state cleanup needed; Terraform retries the failed resource.
Continue to Deploying Terraform for the terraform apply walkthrough, or jump to Quick Start if you want the abbreviated path for returning operators.
← Previous: Quick Start | Next: Deployment Architecture →
"Give me six hours to chop down a tree and I will spend the first four sharpening the axe."
Often attributed to Abraham Lincoln