This document describes the minimal FreeIPA setup for the Astra staging environment on AWS, based on fedora-infra/tiny-stage.
Purpose: Provision a single AlmaLinux EC2 instance for FreeIPA with proper security groups.
Key Features:
- Uses latest AlmaLinux OS 10 AMI
- Instance type:
t3.small(FreeIPA needs reasonable resources; considert3.mediumfor faster installs) - 30 GB encrypted EBS volume
- Security groups for all IPA ports (HTTP/S, LDAP/S, Kerberos, DNS)
- Optional Elastic IP for stable external access
- Generates Ansible inventory automatically
Security Model:
- Web UI + SSH access: restricted to VPC CIDR (no public access)
- LDAP/Kerberos: restricted to VPC CIDR (app instances)
Purpose: Fully automated IPA installation with FAS extensions.
Installation Steps:
- Updates system packages
- Installs
freeipa-server,freeipa-server-dns,python3-ipalib - Runs
ipa-server-installwith DNS setup, no NTP, unattended mode - Clones and installs
freeipa-fasextensions fromgithub.com/fedora-infra/freeipa-fas - Restarts IPA to load FAS plugins
- Verifies FAS commands are available (
ipa fasagreement-help) - Populates test data (FAS agreements, groups, users)
- Creates service account for application LDAP binding
- Grants service account read-only permissions
Test Data Created:
- 20 test users (all password:
password) - FAS agreement: FPCA
- FAS groups: developers, designers, elections, infra, QA, translators, ambassadors
- Users auto-assigned to groups based on FPCA signature
- Member managers (sponsors) for groups
Wired into infra/envs/staging/main.tf:
- FreeIPA module instance in the default VPC subnet
- Outputs for the instance ID, public IP, and LDAP URI
Variables (infra/envs/staging/variables.tf):
key_name: EC2 key pair for instance accessansible_private_key_path: Path to private key for Ansiblefreeipa_hostname: FQDN (for example:ipa.astra-staging.test)freeipa_domain: Domain (for example:astra-staging.test)freeipa_realm: Kerberos realm (for example:ASTRA-STAGING.TEST)freeipa_admin_password: Admin passwordfreeipa_dm_password: Directory Manager passwordfreeipa_ansible_user: SSH user for provisioning
Outputs (infra/envs/staging/outputs.tf):
freeipa_public_ip: Public IP addressfreeipa_ldap_uri: LDAP URI for apps
Based on fedora-infra/freeipa-fas, the following extensions are installed:
fasircnick: IRC nicknamesfaslocale: User locale preferencefastimezone: User timezonefasstatusnote: Account status notefasgpgkeyid: GPG key IDs
fasagreement-add: Create agreements (like FPCA)fasagreement-add-user: Sign user to agreementfasagreement-add-group: Link agreement to groupgroup-add-member-manager: Add sponsors/managersgroup-add(..., fasgroup=True): Create FAS-style groups
- Automatically adds users to
signed_FPCAgroup when they sign FPCA - Groups can require FPCA signature for membership
Current Setup:
- FreeIPA runs its own DNS server for
astra-staging.testdomain - Uses DNS forwarders:
8.8.8.8,8.8.4.4 --no-host-dnsflag used (no reverse DNS zone setup required)
Limitations:
- Internal DNS only works from within AWS VPC
- External access requires
/etc/hostsentries or private DNS zones - For production, use Route53 private hosted zone
Workaround for Staging:
Add to /etc/hosts on local machine:
<FREEIPA_PUBLIC_IP> ipa.astra-staging.test
cd infra/envs/staging
# Ensure you have an SSH key pair
export TF_VAR_key_name="your-key-name"
export TF_VAR_ansible_private_key_path="~/.ssh/your-key.pem"
# Optional: Override passwords
export TF_VAR_freeipa_admin_password="YourAdminPass"
export TF_VAR_freeipa_dm_password="YourDirectoryManagerPass"
terraform init
terraform plan
terraform applyAfter deployment completes:
# Get connection details
terraform output freeipa_public_ip
# Add to /etc/hosts
echo "$(terraform output -raw freeipa_public_ip) ipa.astra-staging.test" | sudo tee -a /etc/hosts
# Access web UI
open https://ipa.astra-staging.test/
# Login: admin / <freeipa_admin_password>
# SSH to IPA server
ssh -i ~/.ssh/your-key.pem ec2-user@$(terraform output -raw freeipa_public_ip)The Django app will automatically connect to FreeIPA using:
- Host:
ipa.astra-staging.test(via VPC private IP) - Service User:
svc_astra - Service Password: From Secrets Manager (populated from variable)
- CA Cert: Downloaded to
infra/ansible/ipa_ca.crt(upload to S3 or embed in image)
Directly Adapted:
- User creation with FAS attributes (
create_fas_test_data.py) - FAS agreement setup (FPCA, automember rules)
- Group structure (developers, designers, elections, etc.)
- Member manager functionality (sponsors)
Installation approach: Based on tiny-stage IPA role logic but simplified for single-instance staging use
Not Needed for Staging:
- Multiple VMs (auth, tinystage, separate IPA server)
- Vagrant/libvirt-specific configuration
- Fedora Messaging setup
- FASJSON, Ipsilon, Noggin (separate services tiny-stage runs)
- Mail server (Sendria)
- Complex networking between multiple machines
- NTP configuration (using cloud provider time sync)
- Host DNS reverse zones (not needed for staging)
- Replication/high availability
- ansible-freeipa collection (using direct ipa-server-install)
- AWS Region:
eu-west-1(or override viaaws_region) - VPC CIDR:
10.20.0.0/16(configurable) - SSH Key: You must have an EC2 key pair created
- Ansible: Installed locally to run the FreeIPA playbook
- Python packages:
python-freeipa,fakerinstalled on IPA server (playbook handles this) - Instance Size:
t3.mediumminimum (IPA is resource-intensive) - Storage: 30 GB for IPA data (certificates, LDAP, Kerberos database)
Staging Default: t3.small (2 vCPU, 2 GB RAM)
- FreeIPA includes: LDAP, Kerberos KDC, DNS, Certificate Authority, Web UI
- Installation will be slower but functional for staging/testing
- Low user traffic makes this acceptable
Production Recommended: t3.medium or larger for better performance under load
- EC2
t3.small: ~$15/month (on-demand) - EBS 30 GB: ~$3/month
- Elastic IP: Free while attached, $3.60/month if unattached
- Data transfer: Minimal for staging
Total: ~$18-22/month
Cost Optimization:
- Stop instance when not in use (keep EBS, pay ~$3/month)
- Use spot instances (not recommended for IPA as it needs stability)
- Skip Elastic IP (use dynamic public IP, update /etc/hosts as needed)
Terraform:
- Fully idempotent for the FreeIPA instance provisioning
Ansible:
- Most tasks use
registerandchanged_whenfor proper idempotency - IPA installation check: only runs
ipa-server-installif/etc/ipa/default.confmissing - FAS data population: uses
suppress(DuplicateEntry)to handle reruns - Service account creation: checks for "already exists" errors
Rerunning:
# Safe to rerun
terraform apply
# Manually rerun Ansible only
cd ../..
cd infra/ansible
ansible-playbook -i ../envs/staging/ipa_inventory.ini freeipa_setup.yml# Check instance is running
terraform show | grep instance_state
# Test SSH manually
ssh -o StrictHostKeyChecking=no -i ~/.ssh/key.pem fedora@<PUBLIC_IP>
# Check security group allows SSH from your IP
aws ec2 describe-security-groups --group-ids <SG_ID># SSH to instance
ssh -i ~/.ssh/key.pem fedora@<PUBLIC_IP>
# Check IPA logs
sudo journalctl -u ipa
# Check installation log
sudo cat /var/log/ipaserver-install.log# Verify FAS package installed
python3 -c "import ipaserver.plugins.fasagreement"
# Check IPA can see the plugin
ipa fasagreement-help
# Restart IPA
sudo ipactl restart- Check Ansible version: requires 2.9+
- Check Python on target: requires Python 3.x
- Increase timeout in
null_resourceif needed - Run Ansible manually with
-vvvfor debug output
Not included for simplicity:
- Automated DNS via Route53: Would require private hosted zone
- TLS certificate automation: Currently using self-signed IPA CA
- Backup/restore automation: Not critical for staging
- Multi-AZ/HA setup: Overkill for staging, needs 3+ replicas
- Monitoring/alerting: Dev doesn't need CloudWatch alarms
- FASJSON/Noggin/Ipsilon: Separate services, not required for basic LDAP/Kerberos
If you need any of these, they're straightforward additions to the existing setup.
- tiny-stage: https://github.com/fedora-infra/tiny-stage
- freeipa-fas: https://github.com/fedora-infra/freeipa-fas
- python-freeipa: https://github.com/waldur/python-freeipa
- FreeIPA docs: https://freeipa.readthedocs.io/