Skip to main content
Redhat Developers Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to build virtual machines using Ansible Collections

November 27, 2024
Obinna Ezeakachi
Related topics:
Automation and managementDevOps
Related products:
Red Hat Ansible Automation Platform

Share:

    The Cornerstone Collection is a lab provisioning tool built on Red Hat Ansible Automation Platform. It streamlines the process of creating virtual machines (VMs) across on-premises environments (libvirt) and cloud-based platforms (such as Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform (GCP)). Figure 1 depicts this. In this article, we’ll walk through a simple demonstration of how to deploy a test instance on AWS and GCP using the collection.

    Cornerstone Architecture Diagram
    Figure 1: Cornerstone architecture diagram.

    For those of you who are more text-based learners, you can follow this tutorial to understand how the collection works and how to raise a VM. For others that favor a more visual learning style, you can follow the tutorial in the following videos.

    How does it all work?

    The collection comprises of 2 roles: pre-req-install and cornerstone. Both of them leverage a global vars file called main.yml which lives in a separate directory next to the playbooks that call these roles for the provisioning process. The reason for this is that main.yml contains all the variables that are integral to building the VMs, thus increasing a need for ease of access.

    Playbook ordering:

    ``` [oezeakac@oezeakac-thinkpadt14gen3 cornerstone-playbooks]$ tree . ├── pre-req-run.yml ├── run.yml └── vars └── main.yml ```

    pre-req-install role:

    This role automates the installation and configuration of packages and tools needed to create the virtual machines. The role is utilized via a playbook (pre-req-run.yml) as shown below and uses the main.yml vars file to complete a successful install. If you look at the main.yml excerpt below, you can see examples on what variables to provide to raise the VM in AWS or GCP.

    pre-req-run.yml:

    ``` --- - name: Build Instance hosts: localhost vars_files: - vars/main.yml tasks: - include_role: name: cornerstone.cornerstone.pre_req_install ```

    Full examples can be found below:

    • AWS

    • GCP

    /vars/main.yml (AWS):

    ```yaml aws_system_user: aws_profile: #Ex: profile1 aws_access_key: #access-key aws_secret_key: # secret-key aws_region: #Ex: "eu-west-1" aws_format: #Ex: table foundation: #Ex: "aws" key_name: #Ex: aws_keypair key_file: #Ex: /home/oezeakac/labs/Ansible/cornerstone-playbooks/aws_keypair #non-root dir ansible_python_interpreter: #Ex: /usr/bin/python3.11 cornerstone_prefix: #Ex: cs cornerstone_ssh_admin_username: #Ex: rhadmin cornerstone_ssh_admin_pubkey: #Ex: rsa.pub cornerstone_aws_ssh_key_name: #Ex: "{{ key_name }}" cornerstone_aws_profile: #Ex: default cornerstone_ssh_user: #Ex: ec2-user cornerstone_ssh_key_path: #Ex: "ssh_key.pem" cornerstone_platform: #Ex: aws cornerstone_location: #Ex: eu-west-1 ```

    /vars/main.yml (GCP):

    ```yaml foundation: #Ex: "gcp" ```

    The foundation variable is used to determine set-up tasks that will run under the tasks folder of the role. Take a look at the main.yml file under the tasks directory. If the value of the foundation variable is set to aws then the aws.yml playbook will run and execute aws-related installation tasks. If the foundation variable is set to gcp then the gcp.yml playbook will run and execute GCP-related tasks. The same logic applies for the values Libvrt and Azure.

    /tasks/main.yml:

    ```yaml - name: AWS Pre-Req Install ansible.builtin.include_tasks: "aws.yml" when: foundation == 'aws' - name: Azure Pre-Req Install ansible.builtin.include_tasks: "azure.yml" when: foundation == 'azure' - name: Libvrt Pre-Req Install ansible.builtin.include_tasks: "libvrt.yml" when: foundation == 'libvrt' - name: GCP AWS Pre-Req Install ansible.builtin.include_tasks: "gcp.yml" when: foundation == 'gcp' ```

    When ready populate the vars file with the relevant information and run the playbook with the following command:

    ``` ansible-navigator run pre-req-run.yml ```

    Cornerstone role

    This role carries out the task of creating the virtual machines in their chosen cloud environments.

    run.yml:

    ``` --- - name: Build Instance hosts: localhost vars_files: - vars/main.yml tasks: - include_role: name: cornerstone.cornerstone.Cornerstone ```

    /vars/main.yml (AWS):

    ```yaml cornerstone_sg: - name: "testworkshop-sg" description: Security group for aws region: "{{ cornerstone_location }}" rules: - proto: tcp from_port: 22 to_port: 22 group_name: "" cidr_ip: 0.0.0.0/0 rule_desc: "allowSSHin_all" - proto: tcp from_port: 443 to_port: 443 group_name: "" cidr_ip: 0.0.0.0/0 rule_desc: "allowHttpsin_all" - proto: all from_port: "" to_port: "" group_name: "testworkshop-sg" cidr_ip: 0.0.0.0/0 rule_desc: "allowAllfromSelf" vm_state: present guests: testsystem1: cornerstone_vm_state: #Ex: "{{vm_state}}" cornerstone_platform: #Ex: aws cornerstone_tag_purpose: #Ex: "Testing" cornerstone_tag_role: #Ex: "testsystem" cornerstone_vm_name: #Ex: testsystem cornerstone_location: #Ex: eu-west-1 cornerstone_vm_aws_az: #Ex: eu-west-1a cornerstone_vm_flavour: #Ex: t3.2xlarge cornerstone_vm_aws_ami: #Ex: ami-0b04ce5d876a9ba29 cornerstone_vm_aws_sg: #Ex: obitestworkshop-sg cornerstone_virtual_network_name: #Ex: "{{ cornerstone_prefix }}vnet" cornerstone_virtual_network_cidr: #Ex: "10.1.0.0/16" cornerstone_subnet_name: #Ex: "{{ cornerstone_prefix }}subnet" cornerstone_public_private_ip: #Ex: public cornerstone_vm_private_ip: cornerstone_vm_assign_public_ip: #Ex: yes cornerstone_vm_public_ip: #Ex: 63.34.15.95 cornerstone_publicip_allocation_method: #Ex: Dynamic cornerstone_publicip_domain_name: #Ex: null cornerstone_vm_os_disk_size: #Ex: 10 cornerstone_vm_data_disk: #Ex: false cornerstone_vm_data_disk_device_name: #Ex: "/dev/xvdb" cornerstone_aws_vm_data_disk_managed: #Ex: "gp2" cornerstone_vm_data_disk_size: #Ex: "50" ```

    /vars/main.yml (GCP):

    ```yaml cornerstone_prefix: #Ex: cs cornerstone_platform: #Ex: gcp ansible_python_interpreter: #Ex: /usr/bin/python3.11 cornerstone_gcp_project: #Ex: openenv-d2p2t cornerstone_gcp_auth_kind: #Ex: "serviceaccount" cornerstone_service_account_file: #Ex: /home/oezeakac/labs/Ansible/cornerstone-playbooks/openenv-prbtd-6d274028b755.json - This is the private key cornerstone_virtual_network_name: #Ex: "{{ cornerstone_prefix }}-vnet" cornerstone_location: #Ex: europe-west2 cornerstone_gcp_zone: #Ex: europe-west2-a cornerstone_virtual_network_cidr: #Ex: 172.16.0.0/28 cornerstone_gcp_use_serviceaccount: true cornerstone_ssh_admin_username: root user cornerstone_ssh_admin_pubkey: #<generate pub ssh key and sub in here when running run.yml> ocp4_platform: gcp cornerstone_sg: - name: "cs-sg" description: "firewall rules" rules: - proto: tcp from_port: 22 vm_state: present guests: bastion: cornerstone_platform: #Ex: gcp cornerstone_gcp_project: #Ex: openenv-d2p2t cornerstone_gcp_auth_kind: #Ex: "serviceaccount" cornerstone_service_account_file: "" #Ex:/home/oezeakac/labs/Ansible/cornerstone-playbooks/openenv-prbtd-6d274028b755.json cornerstone_working_dir: #Ex:'/tmp/' cornerstone_vm_state: #Ex:"{{vm_state}}" cornerstone_vm_name: #Ex: "bastion" cornerstone_location: #Ex: europe-west2 cornerstone_gcp_zone: #Ex: europe-west2-a cornerstone_virtual_network_name: #Ex: "{{ cornerstone_prefix }}-vnet" cornerstone_virtual_network_cidr: #Ex: 172.16.0.0/28 cornerstone_subnet_name: #Ex: "{{ cornerstone_prefix }}subnet" cornerstone_vm_flavour: #Ex: e2-medium cornerstone_vm_gcp_source_image: #Ex:"projects/rhel-cloud/global/images/rhel-8-v20230411" cornerstone_vm_os_disk_size: #Ex: 30 cornerstone_tag_purpose: #Ex: "bastion" cornerstone_tag_role: #Ex: "testing" ```

    Like the previous role, cornerstone is used via a playbook which leverages the role and main.yml in the vars directory. If you look back at the example vars file above, you can see it contains the configuration information to create the virtual machine in your chosen cloud platform. So if you’ve chosen AWS, things such as VPC, security groups, EC2 flavor, and etc. are all detailed here. The cornerstone-platform variable determines the type of tasks that need to be run to complete provisioning. Under the tasks folder the main.yml checks the value of cornerstone-platform and if it’s set to e.g., aws, all the task files that are AWS-specific are run. The same goes for GCP if the value of the variable is set to gcp.

    Run the playbook using the command below:

    ``` ansible-navigator run run.yml ```

    Once that’s complete you can head to the AWS console and check under the EC2 Dashboard to confirm that a test instance has been created. See Figure 2.

    Evidence of Ec2 instance being raised in AWS via Cornerstone
    Figure 2: Evidence of Ec2 instance being raised in AWS via Cornerstone.

    For the bastion server in GCP, if you log into the console you can see that’s been generated (Figure 3).

    Evidence of gcp instance being raised in GCP via Cornerstone
    Figure 3: Evidence of GCP instance being raised in GCP via Cornerstone.

    References

    • Cornerstone Collection
    • Cornerstone EE
    • Cornerstone Playbooks
    • ansible-role-cornerstone

    Related Posts

    • Ansible Collection for Red Hat Runtimes

    • Create AWS resources with Kubernetes and Operators

    • Deploying SQL Server on Linux using an Ansible playbook

    • How to create a GCP instance using Ansible Automation

    • How to use Ansible Automation Platform from GCP Marketplace

    • Generate Ansible Playbooks using natural language prompts

    Recent Posts

    • LLM Compressor 0.8.0: Extended support for Qwen3 and more

    • Master KV cache aware routing with llm-d for efficient AI inference

    • Deploying OpenShift hosted clusters with Hypershift

    • Signing RPM packages using quantum-resistant cryptography

    • using the Argo CD Agent with OpenShift GitOps

    What’s up next?

    Learn the basics of YAML, a simple yet powerful data serialization language, through examples using Ansible.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue