Deploying SAP Cloud Connector (SCC) on AWS Free Tier Using Terraform + Ansible + SLES

Estimated read time 12 min read

I’ve spent a bit of time experimenting with Cloud Connectors recently and wanted a faster, cleaner way to spin one up without all the usual hassle. In this post, I build on the earlier SCC and Ansible write-ups and bring everything together into a single workflow. We’ll automate the entire deployment using Terraform for provisioning and Ansible for configuration, resulting in a fully working SCC with minimal manual effort.

This guide provides a fully working, fully automated setup using:

Terraform for provisioning the EC2 instanceAnsible for OS prep and SCC installationHeap tuning via props.ini for stable SCC operation

1. Directory layout

sap-lab/
├── run.sh
├── run_destroy.sh

├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ ├── terraform.tfvars
│ └── <KEYPAIR_NAME>.pub

└── ansible/
├── site.yml
├── inventory.ini
├── ansible.cfg
└── roles/
├── sap_prep/
│ └── tasks/main.yml
└── sap_scc/
├── defaults/main.yml
├── tasks/main.yml
└── templates/scc_daemon.service.j2

2. Terraform: main.tf

terraform {
required_version = “>= 1.5”
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}

provider “aws” {
region = var.region
}

resource “aws_security_group” “sap_scc_sg” {
name = “sap-scc-sg”
description = “Allow SCC UI and SSH”
vpc_id = var.vpc_id

ingress {
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}

ingress {
from_port = 8443
to_port = 8443
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}

egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}
}

resource “aws_instance” “sap_scc” {
ami = var.sles_ami
instance_type = “t2.micro”
key_name = var.keypair_name

subnet_id = var.subnet_id
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.sap_scc_sg.id]

tags = {
Name = “SAP-LAB-SCC”
}
}

output “ansible_inventory” {
value = “sap_host ansible_host=${aws_instance.sap_scc.public_ip} ansible_user=ec2-user ansible_ssh_private_key_file=../terraform/${var.private_key} ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'”
}

3. Terraform Variables (variables.tf)

variable “region” {}
variable “vpc_id” {}
variable “subnet_id” {}
variable “keypair_name” {}
variable “private_key” {}
variable “sles_ami” {}

4. terraform.tfvars

region = “us-east-2”
vpc_id = “vpc-xxxxxxxxxxxxxxxx”
subnet_id = “subnet-xxxxxxxxxxxx”
keypair_name = “my-keypair”
private_key = “my-keypair.pem”
sles_ami = “ami-xxxxxxxxxxxxxxxx”

5. Ansible config (ansible.cfg)

[defaults]
host_key_checking = False
retry_files_enabled = False

6. Role: OS Preparation (sap_prep/tasks/main.yml)


– name: Install prerequisites
zypper:
name:
– wget
– net-tools
– chrony
– unzip
– curl
state: present

– name: Ensure chronyd is running
service:
name: chronyd
state: started
enabled: yes

– name: Set vm.swappiness
ansible.posix.sysctl:
name: vm.swappiness
value: “10”
state: present
reload: yes

7. SCC Role Defaults (sap_scc/defaults/main.yml)


scc_version: “2.16.2”
scc_file: “sapcc-{{ scc_version }}-linux-x64.zip”

scc_install_dir: /opt/sap/scc
scc_user: sccadm
scc_group: sccadm

scc_jvm_xms: “256m”
scc_jvm_xmx: “512m”

scc_service_name: scc_daemon

8. SCC Installation Tasks (sap_scc/tasks/main.yml)


– name: Ensure sccadm group exists
group:
name: “{{ scc_group }}”
system: yes

– name: Ensure sccadm user exists
user:
name: “{{ scc_user }}”
group: “{{ scc_group }}”
shell: /sbin/nologin
system: yes

– name: Install prerequisites
become: yes
zypper:
name:
– unzip
– curl
– java-17-openjdk-headless
state: present

– name: Create installer directory
file:
path: /tmp/scc-installer
state: directory

– name: Upload SCC ZIP (2.16.2)
copy:
src: sapcc-2.16.2-linux-x64.zip
dest: /tmp/scc-installer/sapcc.zip

– name: Extract SCC ZIP
unarchive:
src: /tmp/scc-installer/sapcc.zip
dest: /tmp/scc-installer
remote_src: yes

– name: Locate SCC RPM
find:
paths: /tmp/scc-installer
patterns: “com.sap.scc-ui-*.rpm”
register: rpm_file

– name: Fail if SCC RPM not found
fail:
msg: “SCC RPM not found.”
when: rpm_file.matched == 0

– name: Install SCC RPM
become: yes
zypper:
name: “{{ rpm_file.files[0].path }}”
disable_gpg_check: yes
state: present

# Heap tuning
– name: Tune Xms
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘-Xms[0-9]+m’
replace: “-Xms{{ scc_jvm_xms }}”

– name: Tune Xmx
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘-Xmx[0-9]+m’
replace: “-Xmx{{ scc_jvm_xmx }}”

– name: Tune NewSize
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘NewSize=[0-9]+m’
replace: ‘NewSize=256m’

– name: Tune MaxNewSize
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘MaxNewSize=[0-9]+m’
replace: ‘MaxNewSize=256m’

– name: Enable SCC daemon
become: yes
systemd:
name: “{{ scc_service_name }}”
enabled: yes

– name: Start SCC daemon
become: yes
systemd:
name: “{{ scc_service_name }}”
state: restarted

9. Systemd Template (scc_daemon.service.j2)

[Unit]
Description=SAP Cloud Connector
After=network.target

[Service]
Type=forking
User={{ scc_user }}
Group={{ scc_group }}
ExecStart=/opt/sap/scc/go.sh -start
ExecStop=/opt/sap/scc/go.sh -stop
Restart=on-failure

[Install]
WantedBy=multi-user.target

10. site.yml


– hosts: sap_hosts
become: true
roles:
– sap_prep
– sap_scc

11. run.sh

#!/bin/bash
set -e

cd terraform
terraform init
terraform apply -auto-approve

INVENTORY=$(terraform output -raw ansible_inventory)

cd ../ansible
echo “[sap_hosts]” > inventory.ini
echo “$INVENTORY” >> inventory.ini

ansible-playbook -i inventory.ini site.yml

Output (from ansible):

Outputs:

public_ip = “<PUBLIC_IP>”

PLAY [sap_hosts] *************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************
[WARNING]: Host ‘ec2-user@<PUBLIC_IP>’ is using the discovered Python interpreter at ‘/usr/bin/python3.13’, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.19/reference_appendices/interpreter_discovery.html for more information.
[WARNING]: sftp transfer mechanism failed on [ec2-user@<PUBLIC_IP>]. Use ANSIBLE_DEBUG=1 to see detailed information
[WARNING]: scp transfer mechanism failed on [ec2-user@<PUBLIC_IP>]. Use ANSIBLE_DEBUG=1 to see detailed information
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Install base packages] **************************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Start chronyd] **********************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Refresh SUSE repos] *****************************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Install Java 17 (OpenJDK)] **********************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Verify Java installation] ***********************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Ensure sccadm group exists] **********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Ensure sccadm user exists] ***********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Install prerequisites] ***************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Create installer directory] **********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Upload SCC ZIP (2.16.2)] *************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Extract SCC ZIP] *********************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Find SCC RPM inside extracted ZIP] ***************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Fail if SCC RPM not found] ***********************************************************************************
skipping: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Install SCC RPM with zypper] *********************************************************************************
changed: [ec

12. Once the SAP Cloud Connector service has started on your SUSE instance, open the administration UI in your browser.

https://<YOUR_PUBLIC_IP>:8443

 From here you can change the default password and connect the SCC up to BTP / on-prem etc.

13. run_destroy.sh

#!/bin/bash
set -e

cd terraform
terraform destroy -auto-approve
cd ..

echo “# destroyed” > ansible/inventory.ini

Conclusion

Fully automated provisioning and configuration of SAP Cloud Connector on SLES using Terraform and Ansible, with JVM tuning for AWS Free Tier. 

 

​ I’ve spent a bit of time experimenting with Cloud Connectors recently and wanted a faster, cleaner way to spin one up without all the usual hassle. In this post, I build on the earlier SCC and Ansible write-ups and bring everything together into a single workflow. We’ll automate the entire deployment using Terraform for provisioning and Ansible for configuration, resulting in a fully working SCC with minimal manual effort.This guide provides a fully working, fully automated setup using:Terraform for provisioning the EC2 instanceAnsible for OS prep and SCC installationHeap tuning via props.ini for stable SCC operation1. Directory layoutsap-lab/
├── run.sh
├── run_destroy.sh

├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ ├── terraform.tfvars
│ └── <KEYPAIR_NAME>.pub

└── ansible/
├── site.yml
├── inventory.ini
├── ansible.cfg
└── roles/
├── sap_prep/
│ └── tasks/main.yml
└── sap_scc/
├── defaults/main.yml
├── tasks/main.yml
└── templates/scc_daemon.service.j22. Terraform: main.tfterraform {
required_version = “>= 1.5”
required_providers {
aws = {
source = “hashicorp/aws”
version = “~> 5.0”
}
}
}

provider “aws” {
region = var.region
}

resource “aws_security_group” “sap_scc_sg” {
name = “sap-scc-sg”
description = “Allow SCC UI and SSH”
vpc_id = var.vpc_id

ingress {
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}

ingress {
from_port = 8443
to_port = 8443
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}

egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}
}

resource “aws_instance” “sap_scc” {
ami = var.sles_ami
instance_type = “t2.micro”
key_name = var.keypair_name

subnet_id = var.subnet_id
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.sap_scc_sg.id]

tags = {
Name = “SAP-LAB-SCC”
}
}

output “ansible_inventory” {
value = “sap_host ansible_host=${aws_instance.sap_scc.public_ip} ansible_user=ec2-user ansible_ssh_private_key_file=../terraform/${var.private_key} ansible_ssh_common_args=’-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'”
}3. Terraform Variables (variables.tf)variable “region” {}
variable “vpc_id” {}
variable “subnet_id” {}
variable “keypair_name” {}
variable “private_key” {}
variable “sles_ami” {}4. terraform.tfvarsregion = “us-east-2”
vpc_id = “vpc-xxxxxxxxxxxxxxxx”
subnet_id = “subnet-xxxxxxxxxxxx”
keypair_name = “my-keypair”
private_key = “my-keypair.pem”
sles_ami = “ami-xxxxxxxxxxxxxxxx”5. Ansible config (ansible.cfg)[defaults]
host_key_checking = False
retry_files_enabled = False6. Role: OS Preparation (sap_prep/tasks/main.yml)—
– name: Install prerequisites
zypper:
name:
– wget
– net-tools
– chrony
– unzip
– curl
state: present

– name: Ensure chronyd is running
service:
name: chronyd
state: started
enabled: yes

– name: Set vm.swappiness
ansible.posix.sysctl:
name: vm.swappiness
value: “10”
state: present
reload: yes7. SCC Role Defaults (sap_scc/defaults/main.yml)—
scc_version: “2.16.2”
scc_file: “sapcc-{{ scc_version }}-linux-x64.zip”

scc_install_dir: /opt/sap/scc
scc_user: sccadm
scc_group: sccadm

scc_jvm_xms: “256m”
scc_jvm_xmx: “512m”

scc_service_name: scc_daemon8. SCC Installation Tasks (sap_scc/tasks/main.yml)—
– name: Ensure sccadm group exists
group:
name: “{{ scc_group }}”
system: yes

– name: Ensure sccadm user exists
user:
name: “{{ scc_user }}”
group: “{{ scc_group }}”
shell: /sbin/nologin
system: yes

– name: Install prerequisites
become: yes
zypper:
name:
– unzip
– curl
– java-17-openjdk-headless
state: present

– name: Create installer directory
file:
path: /tmp/scc-installer
state: directory

– name: Upload SCC ZIP (2.16.2)
copy:
src: sapcc-2.16.2-linux-x64.zip
dest: /tmp/scc-installer/sapcc.zip

– name: Extract SCC ZIP
unarchive:
src: /tmp/scc-installer/sapcc.zip
dest: /tmp/scc-installer
remote_src: yes

– name: Locate SCC RPM
find:
paths: /tmp/scc-installer
patterns: “com.sap.scc-ui-*.rpm”
register: rpm_file

– name: Fail if SCC RPM not found
fail:
msg: “SCC RPM not found.”
when: rpm_file.matched == 0

– name: Install SCC RPM
become: yes
zypper:
name: “{{ rpm_file.files[0].path }}”
disable_gpg_check: yes
state: present

# Heap tuning
– name: Tune Xms
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘-Xms[0-9]+m’
replace: “-Xms{{ scc_jvm_xms }}”

– name: Tune Xmx
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘-Xmx[0-9]+m’
replace: “-Xmx{{ scc_jvm_xmx }}”

– name: Tune NewSize
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘NewSize=[0-9]+m’
replace: ‘NewSize=256m’

– name: Tune MaxNewSize
become: yes
replace:
path: /opt/sap/scc/props.ini
regexp: ‘MaxNewSize=[0-9]+m’
replace: ‘MaxNewSize=256m’

– name: Enable SCC daemon
become: yes
systemd:
name: “{{ scc_service_name }}”
enabled: yes

– name: Start SCC daemon
become: yes
systemd:
name: “{{ scc_service_name }}”
state: restarted9. Systemd Template (scc_daemon.service.j2)[Unit]
Description=SAP Cloud Connector
After=network.target

[Service]
Type=forking
User={{ scc_user }}
Group={{ scc_group }}
ExecStart=/opt/sap/scc/go.sh -start
ExecStop=/opt/sap/scc/go.sh -stop
Restart=on-failure

[Install]
WantedBy=multi-user.target10. site.yml—
– hosts: sap_hosts
become: true
roles:
– sap_prep
– sap_scc11. run.sh#!/bin/bash
set -e

cd terraform
terraform init
terraform apply -auto-approve

INVENTORY=$(terraform output -raw ansible_inventory)

cd ../ansible
echo “[sap_hosts]” > inventory.ini
echo “$INVENTORY” >> inventory.ini

ansible-playbook -i inventory.ini site.ymlOutput (from ansible):Outputs:

public_ip = “<PUBLIC_IP>”

PLAY [sap_hosts] *************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************
[WARNING]: Host ‘ec2-user@<PUBLIC_IP>’ is using the discovered Python interpreter at ‘/usr/bin/python3.13’, but future installation of another Python interpreter could cause a different interpreter to be discovered. See https://docs.ansible.com/ansible-core/2.19/reference_appendices/interpreter_discovery.html for more information.
[WARNING]: sftp transfer mechanism failed on [ec2-user@<PUBLIC_IP>]. Use ANSIBLE_DEBUG=1 to see detailed information
[WARNING]: scp transfer mechanism failed on [ec2-user@<PUBLIC_IP>]. Use ANSIBLE_DEBUG=1 to see detailed information
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Install base packages] **************************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Start chronyd] **********************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Refresh SUSE repos] *****************************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Install Java 17 (OpenJDK)] **********************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_prep : Verify Java installation] ***********************************************************************************
changed: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Ensure sccadm group exists] **********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Ensure sccadm user exists] ***********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Install prerequisites] ***************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Create installer directory] **********************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Upload SCC ZIP (2.16.2)] *************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Extract SCC ZIP] *********************************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Find SCC RPM inside extracted ZIP] ***************************************************************************
ok: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Fail if SCC RPM not found] ***********************************************************************************
skipping: [ec2-user@<PUBLIC_IP>]

TASK [sap_scc : Install SCC RPM with zypper] *********************************************************************************
changed: [ec12. Once the SAP Cloud Connector service has started on your SUSE instance, open the administration UI in your browser.https://<YOUR_PUBLIC_IP>:8443 From here you can change the default password and connect the SCC up to BTP / on-prem etc.13. run_destroy.sh#!/bin/bash
set -e

cd terraform
terraform destroy -auto-approve
cd ..

echo “# destroyed” > ansible/inventory.iniConclusionFully automated provisioning and configuration of SAP Cloud Connector on SLES using Terraform and Ansible, with JVM tuning for AWS Free Tier.    Read More Technology Blog Posts by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author