Ansible Server Provisioning

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"

This post is about Ansible Server Provisioning


From bare metal through function-as-a-service, automating with ansible server provisioning of infrastructure is the first step in automating the operation of your applications. Ansible can provision from cloud platforms and virtualized hosts to hypervisors, network devices, and bare-metal servers.
Bootstrapping the nodes can be connected to storage, added to a load balancer, security patched, or any other operational tasks by separate teams. So, Ansible becomes the connecting tool in any of your process pipelines – automatically taking basic infrastructure right through to day-to-day management.

Ansible Installation & Configuration on CentOS-7
Ansible Installation & Configuration on CentOS-7

Ansible server provisioning Role with Defaults

We’ll start with an Ansible role called hello_web that will install an Apache web server on Centos and have Vagrant bring up the guest system and run the tasks in the role.

Initial Work Area Structure

# mkdir provision-unixcop
# cd provision-unixcop/
# mkdir roles
# ansible-galaxy init roles/provision-unixcop

Vagrant Configuration Ansible Server Provisoning

Now we need to create our Vagrant configuration with this Vagrantfile:

cat Vagrantfile 
Vagrant.configure("2") do |config| = "geerlingguy/centos7" "forwarded_port", guest: 80, host: 8080
  ####### Provision #######
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "apply_provision.yml"
    ansible.verbose = true

The ansible_local provisioner defaults are adequate for our simple role provision-unixcop. The site playbook or the playbook that runs our desired roles for this guest system is called playbook.yml. This will kick off everything we need to make this work.

Create the Playbook

The provisioner picks a playbook to run for the provisioning process. This is where we can select the provision-unixcop role. Update provision/playbook.yml with this:

cat apply_provision.yml 
- hosts: all
  become: true
    - roles/provision-unixcop

Create the Role Defaults

Now we can start digging into the role parts. But, first, let’s set some default variables with defaults that make sense for a Centos system. From within the provision-unixcop role, update tasks/main.yml with this:

cat roles/provision-unixcop/tasks/main.yml 
# tasks file for role/provision-unixcop
- name: Install Apache
    name: httpd
    state: present
- shell: |
     echo " <html>"  > /var/www/html/index.html
     echo "<body>" >> /var/www/html/index.html
     echo "<h1>" >> /var/www/html/index.html
     echo "Hello UnixCop friends" >> /var/www/html/index.html
     echo "</h1>" >> /var/www/html/index.html
     echo "</body>" >> /var/www/html/index.html
     echo " </html>" >> /var/www/html/index.html
- systemd:
     name: httpd
     state: started
     enabled: true

These tasks use three modules (analogous to resources in Chef and Puppet) of yum, systemd, and shell to create our web server and content, and their purpose should be self-explanatory based on the name value for each task to describe what the job does.

Test provisioning

 # vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'geerlingguy/centos7'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'geerlingguy/centos7' version '1.2.26' is up to date...
==> default: Setting the name of the VM: provision-unixcop_default_1657368154853_52472
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 80 (guest) => 8080 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address:
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => /home/neil/provision-unixcop
==> default: Running provisioner: ansible_local...
    default: Installing Ansible...
    default: Running ansible-playbook...
cd /vagrant && PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ansible-playbook --limit="default" --inventory-file=/tmp/vagrant-ansible/inventory -v apply_provision.yml
Using /etc/ansible/ansible.cfg as config file

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [default]

TASK [roles/provision-unixcop : Install Apache] ********************************
changed: [default] => {"changed": true, "changes": {"installed": ["httpd"]}, "msg": "", "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base:\n * epel:\n * extras:\n * updates:\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos.5 for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-7.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package           Arch         Version                     Repository     Size\n================================================================================\nInstalling:\n httpd             x86_64       2.4.6-97.el7.centos.5       updates       2.7 M\nInstalling for dependencies:\n apr               x86_64       1.4.8-7.el7                 base          104 k\n apr-util          x86_64       1.5.2-6.el7                 base           92 k\n httpd-tools       x86_64       2.4.6-97.el7.centos.5       updates        94 k\n mailcap           noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+4 Dependent packages)\n\nTotal download size: 3.0 M\nInstalled size: 10 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              957 kB/s | 3.0 MB  00:03     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : apr-1.4.8-7.el7.x86_64                                       1/5 \n  Installing : apr-util-1.5.2-6.el7.x86_64                                  2/5 \n  Installing : httpd-tools-2.4.6-97.el7.centos.5.x86_64                     3/5 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  4/5 \n  Installing : httpd-2.4.6-97.el7.centos.5.x86_64                           5/5 \n  Verifying  : apr-1.4.8-7.el7.x86_64                                       1/5 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  2/5 \n  Verifying  : httpd-tools-2.4.6-97.el7.centos.5.x86_64                     3/5 \n  Verifying  : apr-util-1.5.2-6.el7.x86_64                                  4/5 \n  Verifying  : httpd-2.4.6-97.el7.centos.5.x86_64                           5/5 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-97.el7.centos.5                                          \n\nDependency Installed:\n  apr.x86_64 0:1.4.8-7.el7                      apr-util.x86_64 0:1.5.2-6.el7   \n  httpd-tools.x86_64 0:2.4.6-97.el7.centos.5    mailcap.noarch 0:2.1.41-2.el7   \n\nComplete!\n"]}

TASK [roles/provision-unixcop : shell] *****************************************
changed: [default] => {"changed": true, "cmd": "echo \" <html>\"  > /var/www/html/index.html\necho \"<body>\" >> /var/www/html/index.html\necho \"<h1>\" >> /var/www/html/index.html\necho \"Hello UnixCop friends\" >> /var/www/html/index.html\necho \"</h1>\" >> /var/www/html/index.html\necho \"</body>\" >> /var/www/html/index.html\necho \" </html>\" >> /var/www/html/index.html\n", "delta": "0:00:00.004133", "end": "2022-07-09 12:08:53.281133", "rc": 0, "start": "2022-07-09 12:08:53.277000", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

TASK [roles/provision-unixcop : systemd] ***************************************
changed: [default] => {"changed": true, "enabled": true, "name": "httpd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "systemd-journald.socket tmp.mount -.mount system.slice", "AllowIsolate": "no", "AmbientCapabilities": "0", "AssertResult": "no", "AssertTimestampMonotonic": "0", "Before": "", "BlockIOAccounting": "no", "BlockIOWeight": "18446744073709551615", "CPUAccounting": "no", "CPUQuotaPerSecUSec": "infinity", "CPUSchedulingPolicy": "0", "CPUSchedulingPriority": "0", "CPUSchedulingResetOnFork": "no", "CPUShares": "18446744073709551615", "CanIsolate": "no", "CanReload": "yes", "CanStart": "yes", "CanStop": "yes", "CapabilityBoundingSet": "18446744073709551615", "CollectMode": "inactive", "ConditionResult": "no", "ConditionTimestampMonotonic": "0", "Conflicts": "", "ControlPID": "0", "DefaultDependencies": "yes", "Delegate": "no", "Description": "The Apache HTTP Server", "DevicePolicy": "auto", "Documentation": "man:httpd(8) man:apachectl(8)", "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "FailureAction": "none", "FileDescriptorStoreMax": "0", "FragmentPath": "/usr/lib/systemd/system/httpd.service", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "httpd.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "18", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "4096", "LimitNPROC": "1856", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "1856", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "httpd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "PermissionsStartOnly": "no", "PrivateDevices": "no", "PrivateNetwork": "no", "PrivateTmp": "yes", "ProtectHome": "no", "ProtectSystem": "no", "RefuseManualStart": "no", "RefuseManualStop": "no", "RemainAfterExit": "no", "Requires": "-.mount system.slice", "RequiresMountsFor": "/var/tmp", "Restart": "no", "RestartUSec": "100ms", "Result": "success", "RootDirectoryStartOnly": "no", "RuntimeDirectoryMode": "0755", "SameProcessGroup": "no", "SecureBits": "0", "SendSIGHUP": "no", "SendSIGKILL": "yes", "Slice": "system.slice", "StandardError": "inherit", "StandardInput": "null", "StandardOutput": "journal", "StartLimitAction": "none", "StartLimitBurst": "5", "StartLimitInterval": "10000000", "StartupBlockIOWeight": "18446744073709551615", "StartupCPUShares": "18446744073709551615", "StatusErrno": "0", "StopWhenUnneeded": "no", "SubState": "dead", "SyslogLevelPrefix": "yes", "SyslogPriority": "30", "SystemCallErrorNumber": "0", "TTYReset": "no", "TTYVHangup": "no", "TTYVTDisallocate": "no", "TasksAccounting": "no", "TasksCurrent": "18446744073709551615", "TasksMax": "18446744073709551615", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "notify", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "disabled", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}

PLAY RECAP *********************************************************************
default                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Ansible server provisioning has other options, such as using Galaxy roles, Host and Group variables, and more. In addition, it can configure and orchestrate not just systems but also networking equipment, web interfaces, and cloud platforms.

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"
Treat your password like your toothbrush. Don’t let anybody else use it, and get a new one every six months.


Please enter your comment!
Please enter your name here

Latest articles

Join us on Facebook