AmICompatible (AIC) is a tool designed to help you test the compatibility of your software across different platforms. Whether you already have a Jenkins pipeline in place or prefer to start with a simple Jenkinsfile that runs your script, AIC can help you quickly identify any compatibility issues with your software.
-
Script Compatibility Testing: Quickly document which Linux distributions your script runs on by creating a Jenkinsfile that just executes the script.
- Example: Deploy an Nginx website => Run with AIC => Discover UFW is missing on some distros => Fix or document it.
-
Software Retrocompatibility: Test how well your software runs across different Windows versions.
-
[Upcoming] Emulation Layer Testing: Check how well your software performs with emulation layers like Wine or Proton for Linux users.
-
Quick Pipeline Execution: Test a Jenkins pipeline without manually setting up a local Jenkins server.
- Python 3.x
- Terraform
- Azure Subscription
- Azure CLI
- Ansible
- Note:
⚠️ Because AIC relies on Ansible, a Linux environment is required. If on Windows, please use WSL or a Linux VM.
-
Clone Repository
git clone https://github.com/IGLADI/AmICompatible && cd AmICompatible
-
Install dependencies
pip install -r requirements.txt
-
Create Azure Service Principal
az login az ad sp create-for-rbac --name "AIC" --role contributor --scopes /subscriptions/<subscription_id>
Note: Alternatively, you can create the Service Principal through the Azure Portal if you prefer not to use the CLI.
-
Edit the configuration file as needed
Copy
aic.yml.example
toaic.yml
:cp aic.yml.example aic.yml
Update
aic.yml
:nano aic.yml
-
Run AIC
This would typically be done using GitHub Actions or similar (which would also handle the secrets in
aic.yml
).python main.py
AIC will install dependencies which might not come with the system. If your code uses these dependencies, it might work on AIC but not on a clean system. For example, Java will be installed by AIC but not present on a clean system.
AIC handles interruptions as much as possible; however, Terraform can be very sensitive to them, so interruptions are still seriously discouraged and you should always check for any cloud resources left when doing so to avoid any unnecessary costs.
Note: If using GitHub Actions, please note that the system forcibly terminates processes after a timeout when canceled, which may not allow enough time for Azure resources to be properly cleaned up. Cancellation is generally unnecessary in CI/CD environments since multiple runs can execute concurrently (each using separate environments with their own
.tfstate
files). Our current implementation only handles theSIGINT
signal, if your CI/CD system uses a different signal, please inform us so we can add support for it.
To add support for additional cloud providers or on-premises infrastructure, follow these steps:
-
Create a new Terraform directory for the provider
mkdir terraform/aws
-
Add Terraform configuration files
Add the necessary Terraform configuration files in the newly created directory to define the infrastructure for the provider.
-
Modify the
main.py
scriptnano main.py
Example:
match cfg["platform"]: case "azure": terraform_dir = "./terraform/azure" case "aws": terraform_dir = "./terraform/aws" case _: print(f"Error: Unsupported platform '{cfg['platform']}' specified.") sys.exit(1)
Note: You could also just change this code to use the provider name as directory name. Don't forget to try catch the
FileNotFoundError
exception.You may also need to update
config.py
to include any provider-specific variables.nano ./modules/config.py
-
Update the configuration file
Ensure that the configuration file (
aic.yml
) includes the new provider and any required variables.
-
Move the existing Terraform files
mv terraform/azure/* terraform/
-
Edit the Terraform files
Update the Terraform files to use environment variables for provider-specific configurations.
-
Modify the
main.py
scriptUpdate the
config.py
script to set the appropriate environment variables based on the provider specified in the configuration.nano ./modules/config.py
Update the
main.py
script to work with one terraform directory.terraform_dir = "./terraform"
-
Update the configuration file
Ensure that the configuration file (
aic.yml
) includes the new provider and any required variables.
To add support for additional operating systems, follow these steps:
-
Update Terraform Main Configuration
Add the new OS to the
source_image_reference
lookup in themain.tf
file for both Windows or Linux configurations.source_image_reference { publisher = lookup({ LinuxUbuntuServer_24_04-LTS = "Canonical", LinuxRhel9 = "RedHat", LinuxDebian12 = "Debian", <new_os> = "<new_publisher>" }, var.os) offer = lookup({ LinuxUbuntuServer_24_04-LTS = "ubuntu-24_04-lts", LinuxRhel9 = "RHEL", LinuxDebian12 = "debian-12", <new_os> = "<new_offer>" }, var.os) sku = lookup({ LinuxUbuntuServer_24_04-LTS = "server", LinuxRhel9 = "90-gen2", LinuxDebian12 = "12-gen2", <new_os> = "<new_sku>" }, var.os) version = "latest" }
-
Update Configuration File
Add the new OS to the
aic.yml
andaic.yml.example
files.os: # - UbuntuServer_24_04-LTS # - Debian12 # - RHEL9 # - <new_os>
-
Add OS-Specific Code
If the new OS requires any specific setup or dependencies, update the corresponding code, this will likely be in the
ansible/linux/dependency.yml
To contribute your changes (like adding support for a new provider), follow these steps:
Fork the repository and clone it to your local machine.
Create a new feature branch.
git checkout -b feature/add-aws-support
Code your changes and commit them.
git add .
git commit -m "Add AWS support"
Push to your fork.
git push origin feature/add-aws-support
ℹ️ Ensure you document your changes and update the README if necessary.
Open a PR on the main repository to merge your changes.
Thank you for contributing to the open-source community!
If you encounter any issue while terraform deploys a specific VM image:
-
Check if your subscription tier is eligible for that image (a lot of images are not available for free plans).
-
Accept TOS when needed:
az vm image terms accept --publisher resf --offer rockylinux-x86_64 --plan 9-base az vm image terms accept --publisher ntegralinc1586961136942 --offer ntg_fedora_41 --plan ntg_fedora_41
ℹ️ We try to keep all TOS commands needed here, if you encounter one not listed here please contribute or open an issue.
If you encounter any issues with terraform, this is most likely due to a mismatch between the tfstate file and the actual resources in the cloud. To fix this, you can delete the tfstate file and delete any resources that were created by the script manually.
rm ./terraform/azure/linux/*.tfstate* > /dev/null 2>&1
rm ./terraform/azure/windows/*.tfstate* > /dev/null 2>&1
ℹ️ You will need to wait for the resources to be deleted before running the script again.
If you encounter an Azure limitation, for example PublicIPCountLimitReached
try decreasing max_threads
in aic.yml
or increase your subscription limits if you are on a paid plan.
The extension has a timeout of ~3 minutes to setup ssh, if you encounter any issues with the extension, try increasing vm_size
in aic.yml
.
If you encounter the error OSError: [Errno 24] Too many open files
, try decreasing max_threads
in aic.yml
.
Check the jenkins.log
file inside the aic_logs
folder. Navigate to the folder of the run you want, then the OS folder you want, and open jenkins.log
. Typically, the information you are interested in will be at the end of the file.
If you encounter any issues, checking the logs can provide more insight into what went wrong. Logs are typically stored in the ~/.aic_logs
directory, this can be changed in the aic.yml
file. The logs contain ansi colors, you can use cat
or other to interpret them, if you want to use vscode to read the logs we recommend the Ansi Colors
extension.