AWS - Deployment
Overview¶
This guide shows how to deploy Rocky Linux from CIQ – Hardened (RLC-H) on Amazon Web Services (AWS) using the AWS CLI.
Prerequisites¶
- Familiarity with AWS concepts (VPCs, Subnets, Security Groups, EC2, IAM, KMS)
- AWS CLI v2 installed and configured (
aws configure) - Rights to accept AWS Marketplace terms and launch EC2/networking resources
- SSH key available (or create/import one below)
Hardware Requirements¶
| Component | Minimum | Recommended |
|---|---|---|
| vCPUs | 2 vCPUs | 4+ vCPUs |
| Memory | 4 GB RAM | 8 GB RAM or more |
| Storage | 25 GB root (AWS default 30) | 64 GB+ gp3 / io2 |
| EC2 Type | t3.medium (2 vCPU, 4 GB) | t3.xlarge (4 vCPU, 16 GB) |
Notes
- AWS often defaults root volumes to 30 GB, which meets the 25 GB minimum.
- gp3 (or io2) volumes are strongly recommended for production workloads.
- ENA (enhanced networking) is enabled by default on most modern instance families.
- Consider extra headroom (≥ 8 GB RAM) when running with LKRG and hardened memory.
How to Acquire RLC-H via Marketplace¶
- Navigate to AWS Marketplace and search for “Rocky Linux Hardened CIQ”.
- Click Continue to Subscribe, then Accept terms for your account/region (one-time).
- After subscribing, you can deploy via the AWS Console or CLI using the Marketplace AMI.
- For CLI usage, you must accept terms first in the Marketplace console.
Note
The Marketplace subscription step only needs to be done once per AWS account/region. After that, you can deploy as many RLC-H EC2 instances as you like using CLI, Terraform, etc.
Marketplace Information¶
RLC-H AMIs are published by CIQ (AWS account ID 679593333241).
A common AMI naming pattern is: RLC-9-Hardened*.
Support Tiers¶
| AMI Name Pattern | Owner (Account ID) | Support Tier |
|---|---|---|
RLC-9-Hardened* |
679593333241 |
Basic Support |
| Coming soon | Coming soon | Standard Support |
| Coming soon | Coming soon | Premium Support |
When creating the instance, specify the AMI ID that matches your desired support level.
Note
For details about CIQ’s support tiers (Basic, Standard, Premium) and what each includes, see CIQ Support Services.
Accept plan terms (one time per account/region)¶
Before performing the below steps please make sure to accep the terms by opening the product page in AWS Marketplace and click Continue to Subscribe → Accept terms for your selected region.
Find the RLC-H image¶
Set your target region¶
AWS_REGION=us-east-1 # adjust to your AWS region
List available hardened images¶
aws ec2 describe-images \
--region "$AWS_REGION" \
--owners 679593333241 \
--filters "Name=name,Values=RLC-9-Hardened*" "Name=virtualization-type,Values=hvm" \
--query 'Images[].{Name:Name,ImageId:ImageId,CreationDate:CreationDate}' \
| jq -r 'sort_by(.CreationDate) | reverse | .[]'
Copy the AMI ID¶
Example: ami-0980002c0adf7401b
AMI_ID="ami-0980002c0adf7401b"
Create VPC and networking¶
VPC_CIDR="10.10.0.0/16"
SUBNET_CIDR="10.10.1.0/24"
SG_NAME="rlch-sg"
KEY_NAME="rlch-key"
INSTANCE_NAME="vm-rlch"
AWS_REGION=${AWS_REGION:-us-east-1}
VPC¶
Create the VPC.
VPC_ID=$(aws ec2 create-vpc \
--cidr-block "$VPC_CIDR" \
--query 'Vpc.VpcId' \
--output text \
--region "$AWS_REGION")
Enable DNS support and DNS hostnames (Optional).
aws ec2 modify-vpc-attribute --vpc-id "$VPC_ID" --enable-dns-support "{\"Value\":true}" --region "$AWS_REGION"
aws ec2 modify-vpc-attribute --vpc-id "$VPC_ID" --enable-dns-hostnames "{\"Value\":true}" --region "$AWS_REGION"
Subnet (use ranges appropriate for your environment)¶
Get the availability zone.
AZ=$(aws ec2 describe-availability-zones \
--region "$AWS_REGION" \
--query 'AvailabilityZones[0].ZoneName' \
--output text)
Create subnets.
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id "$VPC_ID" \
--cidr-block "$SUBNET_CIDR" \
--availability-zone "$AZ" \
--query 'Subnet.SubnetId' \
--output text \
--region "$AWS_REGION")
Internet Gateway¶
Create the Internet Gateway.
IGW_ID=$(aws ec2 create-internet-gateway \
--query 'InternetGateway.InternetGatewayId' \
--output text \
--region "$AWS_REGION")
Attach Internet Gateway to your VPC.
aws ec2 attach-internet-gateway --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID" --region "$AWS_REGION"
Route Table¶
Create route table.
RTB_ID=$(aws ec2 create-route-table \
--vpc-id "$VPC_ID" \
--query 'RouteTable.RouteTableId' \
--output text \
--region "$AWS_REGION")
Add the default route (0.0.0.0/0) to the Internet Gateway
aws ec2 create-route \
--route-table-id "$RTB_ID" \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id "$IGW_ID" \
--region "$AWS_REGION"
Associate the route table with your subnet.
aws ec2 associate-route-table --route-table-id "$RTB_ID" --subnet-id "$SUBNET_ID" --region "$AWS_REGION"
Security Group: allow SSH (harden further as needed)¶
Create the security group: This command creates a new security group named $SG_NAME in VPC $VPC_ID and captures its ID into SG_ID for later use.
SG_ID=$(aws ec2 create-security-group \
--group-name "$SG_NAME" \
--description "RLC-H SG" \
--vpc-id "$VPC_ID" \
--query 'GroupId' \
--output text \
--region "$AWS_REGION")
Allow SSH ingress: This command adds an inbound rule permitting TCP port 22 to the security group SG_ID from the specified CIDR (shown as 0.0.0.0/0 here—replace with your admin/VPN CIDR).
aws ec2 authorize-security-group-ingress \
--group-id "$SG_ID" \
--protocol tcp --port 22 \
--cidr 0.0.0.0/0 \
--region "$AWS_REGION"
Create or use an SSH key pair¶
You need an EC2 key pair in the same region/account you’re launching in. Pick ONE of the options below.
Option A — Create a new key pair¶
KEY_NAME=rlch-key
aws ec2 create-key-pair \
--region "$AWS_REGION" \
--key-name "$KEY_NAME" \
--query 'KeyMaterial' \
--output text > "${KEY_NAME}.pem"
chmod 600 "${KEY_NAME}.pem"
Option B — Import your existing public key as a key pair¶
KEY_NAME=rlch-key
aws ec2 import-key-pair \
--region "$AWS_REGION" \
--key-name "$KEY_NAME" \
--public-key-material fileb://~/.ssh/id_rsa.pub
Option C — Use an existing key pair¶
aws ec2 describe-key-pairs \
--region "$AWS_REGION" \
--query 'KeyPairs[].KeyName' --output text
Then set:
KEY_NAME=<an-existing-key-name>
Note
Key pairs are regional. If you created/imported rlch-key in a different region, it will not be visible here. Keep --region "$AWS_REGION" consistent across all commands.
Create the EC2 instance¶
INSTANCE_TYPE="t3.xlarge"
INSTANCE_NAME="vm-rlch"
INSTANCE_ID=$(aws ec2 run-instances \
--image-id "$AMI_ID" \
--instance-type "$INSTANCE_TYPE" \
--key-name "$KEY_NAME" \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$SG_ID" \
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"VolumeSize":128,"VolumeType":"gp3","Encrypted":true}}]' \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=$INSTANCE_NAME}]" \
--query 'Instances[0].InstanceId' \
--output text \
--region "$AWS_REGION")
Verify the instance¶
Get the public IP¶
aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[0].Instances[0].PublicIpAddress' \
--output text \
--region "$AWS_REGION"
SSH in and confirm RLC-H¶
ssh -i ./rlch-key.pem rocky@<PUBLIC_IP> # or use your matching private key file
cat /etc/os-release
rpm -qa | grep lkrg
Note
The default SSH user is rocky. You must use the private key that matches the EC2 KeyName used at launch. If you imported ~/.ssh/id_rsa.pub under a KeyName, use -i ~/.ssh/id_rsa.
Next steps¶
- Tighten Security Group source scopes (e.g., your admin IP or VPN CIDR instead of
0.0.0.0/0) - Enable CloudWatch metrics/logs and AWS Systems Manager for inventory, patching, and automation
- Attach additional EBS data volumes with
aws ec2 create-volume/aws ec2 attach-volume
Best Practices for RLC-H on AWS¶
Security¶
- Integrate with IAM and use IAM Roles for EC2 (avoid long-lived credentials)
- Enable EBS encryption with customer-managed keys (KMS CMK)
- Restrict traffic using Security Groups and optionally Network ACLs
- Enable CloudTrail, GuardDuty, and Inspector; forward logs to CloudWatch Logs
- Apply AWS Config rules to enforce baseline security configurations and compliance
Performance with Security¶
- Use gp3 or io2 EBS for production workloads
- Ensure ENA is active on supported instance types for high-throughput, low-latency networking
- Monitor LKRG runtime overhead on security-sensitive workloads
- Use Placement Groups (cluster/partition) for tightly coupled, latency-sensitive apps
Compliance¶
- Tag all resources with appropriate governance/compliance metadata
- Use AWS Systems Manager Patch Manager for OS/package patching
- Implement AWS Config conformance packs and remediation
- Run regular posture assessments and follow Security Hub / GuardDuty recommendations
High Availability¶
- Deploy across multiple Availability Zones
- Use cross-AZ strategies for critical data (e.g., EBS snapshots, EFS, replicated databases)
- Implement application health checks and use Elastic Load Balancing
- Configure AWS Backup (with encryption) for automated recovery
For additional security configurations and troubleshooting, see the main RLC-H documentation