This walkthrough demonstrates how to provision a lightweight SLES instance using Terraform, then automatically configure it using Ansible. The result is a clean, automated pipeline that can build and prepare a small SAP-style lab environment in minutes.
All identifying information (AWS account details, VPC IDs, Subnets, AMI IDs, SSH key names, IP addresses, etc.) is represented using placeholders.
Overview
This setup uses two main components:
1. Terraform (Infrastructure)
A SLES EC2 instanceA minimal security groupAn SSH key pair referenceAn Ansible-ready inventory line (via Terraform outputs)
2. Ansible (Configuration)
Basic packageschronyd for time synchronisationSimple SAP-friendly sysctl tuning
No SAP software is installed here. This is a lightweight foundation for further SAP experimentation.
Directory Structure
sap-lab/
├── run.sh
├── run_destroy.sh
│
├── terraform/
│ ├── main.tf
│ ├── <SSH_PUBLIC_KEY_FILENAME>.pub
│ └── terraform.tfstate (generated automatically)
│
└── ansible/
├── inventory.ini
├── site.yml
└── ansible.cfg
Terraform: main.tf
The following main.tf provisions a SLES instance and generates an Ansible inventory line.
terraform {
required_version = “>= 1.5”
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}
provider “aws” {
region = “<AWS_REGION>” # e.g. us-east-2
}
resource “aws_key_pair” “ssh_key” {
key_name = “<KEY_NAME>” # e.g. sap-lab-key
public_key = file(“${path.module}/<SSH_PUBLIC_KEY_FILENAME>.pub”)
}
resource “aws_security_group” “sap_host_sg” {
name = “sap-host-sg”
description = “Security group for SAP lab host”
vpc_id = “<VPC_ID>”
ingress {
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”] # adjust for production
}
egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}
tags = {
Name = “sap-host-sg”
}
}
resource “aws_instance” “sap_host” {
ami = “<SLES_AMI_ID>” # generic placeholder
instance_type = “t2.micro”
key_name = aws_key_pair.ssh_key.key_name
subnet_id = “<SUBNET_ID>”
associate_public_ip_address = true
vpc_security_group_ids = [
aws_security_group.sap_host_sg.id
]
tags = {
Name = “SAP-LAB-Host”
}
}
output “ansible_inventory_line” {
description = “Ansible inventory line for this host”
value = “sap_host ansible_host=<EC2_PUBLIC_IP> ansible_user=ec2-user ansible_ssh_private_key_file=<PATH_TO_PRIVATE_KEY>/<SSH_PRIVATE_KEY_FILENAME>.pem ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'”
}
Ansible: site.yml
—
– name: Prepare host for SAP-style workloads
hosts: sap_hosts
become: true
tasks:
– name: Install basic packages
ansible.builtin.zypper:
name:
– wget
– net-tools
– chrony
state: present
– name: Ensure chronyd is enabled and running
ansible.builtin.service:
name: chronyd
state: started
enabled: yes
– name: Set SAP-friendly sysctl values
ansible.posix.sysctl:
name: vm.swappiness
value: “10”
state: present
reload: yes
Ansible: inventory.ini
[sap_hosts]
sap_host ansible_host=<EC2_PUBLIC_IP> ansible_user=ec2-user ansible_ssh_private_key_file=<PATH_TO_PRIVATE_KEY>/<SSH_PRIVATE_KEY_FILENAME>.pem ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null’
Automation script: run.sh
#!/usr/bin/env bash
set -e
echo “=== Terraform apply ===”
cd terraform
terraform init -input=false
terraform apply -auto-approve -input=false
echo “=== Extracting host info for Ansible ===”
INVENTORY_LINE=$(terraform output -raw ansible_inventory_line)
cd ../ansible
echo “=== Writing inventory.ini ===”
{
echo “[sap_hosts]”
echo “$INVENTORY_LINE”
} > inventory.ini
echo “=== Running Ansible playbook ===”
ansible-playbook -i inventory.ini site.yml
Automation script: run_destroy.sh
#!/usr/bin/env bash
set -e
echo “=== Terraform destroy ===”
cd terraform
terraform destroy -auto-approve -input=false
cd ..
echo “=== Clearing Ansible inventory ===”
echo “# Inventory cleared after destroy” > ansible/inventory.ini
Running the lab
Build the environment
./run.sh
Destroy the environment
./run_destroy.sh
Conclusion
This tutorial provides a simple, repeatable way to spin up SAP-friendly Linux hosts on AWS: Terraform handles the infrastructure, and Ansible handles configuration. From here, you can extend the playbook with SAP Host Agent installation, Cloud Connector setup, or full SAP system preparation, while keeping the core workflow automated and reproducible.
This walkthrough demonstrates how to provision a lightweight SLES instance using Terraform, then automatically configure it using Ansible. The result is a clean, automated pipeline that can build and prepare a small SAP-style lab environment in minutes.All identifying information (AWS account details, VPC IDs, Subnets, AMI IDs, SSH key names, IP addresses, etc.) is represented using placeholders.OverviewThis setup uses two main components:1. Terraform (Infrastructure)A SLES EC2 instanceA minimal security groupAn SSH key pair referenceAn Ansible-ready inventory line (via Terraform outputs)2. Ansible (Configuration)Basic packageschronyd for time synchronisationSimple SAP-friendly sysctl tuningNo SAP software is installed here. This is a lightweight foundation for further SAP experimentation.Directory Structuresap-lab/
├── run.sh
├── run_destroy.sh
│
├── terraform/
│ ├── main.tf
│ ├── <SSH_PUBLIC_KEY_FILENAME>.pub
│ └── terraform.tfstate (generated automatically)
│
└── ansible/
├── inventory.ini
├── site.yml
└── ansible.cfgTerraform: main.tfThe following main.tf provisions a SLES instance and generates an Ansible inventory line.terraform {
required_version = “>= 1.5”
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}
provider “aws” {
region = “<AWS_REGION>” # e.g. us-east-2
}
resource “aws_key_pair” “ssh_key” {
key_name = “<KEY_NAME>” # e.g. sap-lab-key
public_key = file(“${path.module}/<SSH_PUBLIC_KEY_FILENAME>.pub”)
}
resource “aws_security_group” “sap_host_sg” {
name = “sap-host-sg”
description = “Security group for SAP lab host”
vpc_id = “<VPC_ID>”
ingress {
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”] # adjust for production
}
egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}
tags = {
Name = “sap-host-sg”
}
}
resource “aws_instance” “sap_host” {
ami = “<SLES_AMI_ID>” # generic placeholder
instance_type = “t2.micro”
key_name = aws_key_pair.ssh_key.key_name
subnet_id = “<SUBNET_ID>”
associate_public_ip_address = true
vpc_security_group_ids = [
aws_security_group.sap_host_sg.id
]
tags = {
Name = “SAP-LAB-Host”
}
}
output “ansible_inventory_line” {
description = “Ansible inventory line for this host”
value = “sap_host ansible_host=<EC2_PUBLIC_IP> ansible_user=ec2-user ansible_ssh_private_key_file=<PATH_TO_PRIVATE_KEY>/<SSH_PRIVATE_KEY_FILENAME>.pem ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'”
}Ansible: site.yml—
– name: Prepare host for SAP-style workloads
hosts: sap_hosts
become: true
tasks:
– name: Install basic packages
ansible.builtin.zypper:
name:
– wget
– net-tools
– chrony
state: present
– name: Ensure chronyd is enabled and running
ansible.builtin.service:
name: chronyd
state: started
enabled: yes
– name: Set SAP-friendly sysctl values
ansible.posix.sysctl:
name: vm.swappiness
value: “10”
state: present
reload: yesAnsible: inventory.ini[sap_hosts]
sap_host ansible_host=<EC2_PUBLIC_IP> ansible_user=ec2-user ansible_ssh_private_key_file=<PATH_TO_PRIVATE_KEY>/<SSH_PRIVATE_KEY_FILENAME>.pem ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null’Automation script: run.sh#!/usr/bin/env bash
set -e
echo “=== Terraform apply ===”
cd terraform
terraform init -input=false
terraform apply -auto-approve -input=false
echo “=== Extracting host info for Ansible ===”
INVENTORY_LINE=$(terraform output -raw ansible_inventory_line)
cd ../ansible
echo “=== Writing inventory.ini ===”
{
echo “[sap_hosts]”
echo “$INVENTORY_LINE”
} > inventory.ini
echo “=== Running Ansible playbook ===”
ansible-playbook -i inventory.ini site.ymlAutomation script: run_destroy.sh#!/usr/bin/env bash
set -e
echo “=== Terraform destroy ===”
cd terraform
terraform destroy -auto-approve -input=false
cd ..
echo “=== Clearing Ansible inventory ===”
echo “# Inventory cleared after destroy” > ansible/inventory.iniRunning the labBuild the environment./run.shDestroy the environment./run_destroy.shConclusionThis tutorial provides a simple, repeatable way to spin up SAP-friendly Linux hosts on AWS: Terraform handles the infrastructure, and Ansible handles configuration. From here, you can extend the playbook with SAP Host Agent installation, Cloud Connector setup, or full SAP system preparation, while keeping the core workflow automated and reproducible. Read More Technology Blog Posts by Members articles
#SAP
#SAPTechnologyblog