[HowTo] Setup Embedded Ansible


#1

I just downloaded Fine Beta 1 to test Embedded Ansible. However, when I try to activate the role, it fails. I finally managed to get it working. Here is what I did:

Install additional software

I created the repo file for Ansible Tower: /etc/yum.repos.d/ansible-tower.repo.

[ansible-tower]
name=Ansible Tower Repository - $releasever $basearch
baseurl=http://releases.ansible.com/ansible-tower/rpm/epel-7-$basearch
enabled=1
gpgcheck=0

And the one for RabbitMQ: /etc/yum.repos.d/jlaska-rabbitmq.repo.

[jlaska-rabbitmq]
name=Copr repo for rabbitmq owned by jlaska
baseurl=https://copr-be.cloud.fedoraproject.org/results/jlaska/rabbitmq/epel-7-$basearch/
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/jlaska/rabbitmq/pubkey.gpg
enabled=1
enabled_metadata=1

And finally the repo file for PostgreSQL 9.4: /etc/yum.repos.d/pgdg-94-centos.repo.

[pgdg94]
name=PostgreSQL 9.4 $releasever - $basearch
baseurl=http://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-$releasever-$basearch
enabled=1
gpgcheck=0

Then, I installed the required packages:

# yum install -y ansible
# yum install -y rabbitmq-server --disablerepo=epel
# yum install -y ansible-tower-setup \
    nginx supervisor \
    ansible-tower ansible-tower-server ansible-tower-ui

Bootstrap the Ansible Tower environment

I also had to create some assets that make the install fail when missing:

# groupadd -g 989 awx
# useradd -u 992 -g 989 -d /var/lib/awx -s /bin/bash awx
# install -o awx -g awx -d /etc/tower
# cat > /etc/sysconfig/ansible-tower << EOF
TOWER_SERVICES="rabbitmq-server nginx supervisord"
EOF
# install -o awx -g awx -m 0755 -d /var/log/tower
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/callback_receiver.log
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/fact_receiver.log
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/task_system.log
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower.log
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower_rbac_migrations.log
# install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower_system_track_migrations.log

Now, it becomes tricky. When you enable the Embedded Ansible role, ManageIQ launches ansible-tower-setup with a generated inventory stored in /tmp/miq_inventory*.

The installation handles creating the database schema and bootstrapping the data. However, the database password is generated by ManageIQ and is not available before the first run of ansible-tower-setup. That’s a chicken/egg issue, but we can get it from the inventory.

Once the installation playbook finishes, ManageIQ starts Ansible Tower and validates the connection. As we don’t have a valid license, the connection fails with a HTTP 402 error and ManageIQ kills Ansible Tower. Fortunately, ManageIQ tries regularly to deploy the worker and starts Ansible Tower on short periods of time. This gives us a time window to upload a license through the Ansible Tower API.

So, the first step is to get the as database and admin passwords, which are stored in the temporary inventory file. The file is timestamped, so it is quite easy to get the installation information.

# cat /tmp/miq_inventory20170425-1617-9qmuet
[tower]
localhost ansible_connection=local

[database]

[all:vars]
admin_password='Redhat01'

pg_host='localhost'
pg_port='5432'

pg_database='awx'
pg_username='awx'
pg_password='Redhat01'

rabbitmq_port=5672
rabbitmq_vhost=tower
rabbitmq_username='tower'
rabbitmq_password='0123456789abcdef'
rabbitmq_cookie=cookiemonster
rabbitmq_use_long_name=false
rabbitmq_enable_manager=false

Once we have the passwords, we can create the database and the user, with the aforementioned database password:

# su - postgres -c "psql -c \"CREATE ROLE awx SUPERUSER LOGIN PASSWORD 'Redhat01'\""
# su - postgres -c "psql -c \"CREATE DATABASE awx\""

We also need a license. In my case, I requested a temporary license on Ansible website: https://www.ansible.com/tower-trial. We receive it by email and it is a JSON formatted structure. We copy and paste it in a JSON file on our ManageIQ instance. As we inject the license through the Ansible Tower API, we need to extend the license file to say we accept the End User License Agreement (EULA) : it is done by adding "eula_accepted": "true" to the JSON hash.

# cat > /root/tower_license.json << EOF
{
    "eula_accepted": "true",
    "company_name": "Example.com",
    "contact_email": "tower-admin@example.com",
    "contact_name": "Tower Admin",
    "hostname": "0123456789abcdef0123456789abcdef",
    "instance_count": 50,
    "license_date": 1524597966,
    "license_key": "4b2d74b7aa7bbd9bd6eaaa3f99553e158e0ef1605ce8b3faae183ce190fd72ca",
    "license_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "license_type": "enterprise",
    "subscription_name": "Ansible Tower by Red Hat (50 Managed Nodes)",
    "trial": true
}
EOF

So, now we are ready to inject the license. To do so, simply check that Ansible Tower processes are running.

# ps -edf | grep tower
awx       1228 27064  0 10:43 ?        00:00:00 python /usr/bin/tower-manage celery worker -l debug --autoscale=50,4 -Ofair -Q projects,jobs,default,scheduler,broadcast_all,localhost -n celery@localhost
awx      26760     1  0 10:19 ?        00:00:00 python /usr/bin/tower-manage run_callback_receiver
awx      27058 26528  0 10:19 ?        00:00:01 python /usr/bin/tower-manage runworker --only-channels websocket.*
awx      27059 26528  0 10:19 ?        00:00:00 /var/lib/awx/venv/tower/bin/uwsgi --socket :8050 --module=awx.wsgi:application --vacuum --processes=5 --harakiri=120 --no-orphans --master --max-requests=1000 --master-fifo=/var/lib/awx/awxfifo --lazy-apps
awx      27060 26528  0 10:19 ?        00:00:01 python /usr/bin/tower-manage run_fact_cache_receiver
awx      27061 26528  1 10:19 ?        00:00:27 /var/lib/awx/venv/tower/bin/python /var/lib/awx/venv/tower/bin/daphne -b 127.0.0.1 -p 8051 awx.asgi:channel_layer
awx      27063 26528  0 10:19 ?        00:00:02 python /usr/bin/tower-manage celery beat -l debug --pidfile= -s /var/lib/awx/beat.db
awx      27064 26528  0 10:19 ?        00:00:04 python /usr/bin/tower-manage celery worker -l debug --autoscale=50,4 -Ofair -Q projects,jobs,default,scheduler,broadcast_all,localhost -n celery@localhost
awx      27078 27059  0 10:19 ?        00:00:04 /var/lib/awx/venv/tower/bin/uwsgi --socket :8050 --module=awx.wsgi:application --vacuum --processes=5 --harakiri=120 --no-orphans --master --max-requests=1000 --master-fifo=/var/lib/awx/awxfifo --lazy-apps
[...]

And shoot:

# curl -k -u 'admin:0123456789abcdef' https://localhost:54322/api/v1/config/ \
    -X POST -H 'Content-Type: application/json' -d @license.json

If you miss the window, no worries: ManageIQ will start the Ansible Tower a few seconds later and you’ll have as many tries as you need.

Connecting to Ansible Tower

ManageIQ creates a native relationship with the embedded Ansible Tower, but you may want to be able to access the embedded Ansible Tower instance. To do so, simply enable the firewall port it listens on:

# firewall-cmd --permanent --add-port 543222/tcp
# firewall-cmd --reload

If you use the pre-built appliance, the command is slightly different:

# firewall-cmd --permanent --zone manageiq --add-port 54322/tcp
# firewall-cmd --reload

Hope that helps.


How to integrate or activate Ansible in manageIQ fine
Embedded Ansible using AWX
Adding New Repositories
Embedded Ansible in Fine-1
#2

Hi @fdupont,

So I have some input that may make this a bit easier.

# yum install -y ansible
# yum install -y rabbitmq-server --disablerepo=epel
# yum install -y ansible-tower-setup \
    nginx supervisor \
    ansible-tower ansible-tower-server ansible-tower-ui

You should only need to install ansible-tower-setup and ansible-tower-server the rest will be taken care of by dependencies. Also, the “embedded” ansible is intended to be “headless” (for use only through the API) so that is why you had issues with assets as well.

Specifically this [1] option given to the setup script tells it not to attempt to configure the installation for use through the standard web interface.

I also had to create some assets that make the install fail when missing:

You shouldn’t need to do any of this if you don’t attempt to install the UI :point_up:

However, the database password is generated by ManageIQ and is not available before the first run of ansible-tower-setup

Actually we generate the password before the first run of the setup here so you should be able to retrieve the password using MiqDatabase.first.ansible_admin_authentication.password in the rails console (vmdb; bin/rails c).

The database and database role should also have been created at the first attempt to run the setup, so that step shouldn’t be needed either.


Having said all of that, I was able to get the role up and running with just a few commands:

  • Install repo files
  • yum install -y ansible-tower-setup ansible-tower-server
  • vmdb
  • bin/rails r 'EmbeddedAnsible.start; puts MiqDatabase.first.ansible_admin_authentication.password'
  • curl -k -u 'admin:<tower_password>' https://localhost:54322/api/v1/config/ -X POST -H 'Content-Type: application/json' -d @path/to/licence.json
  • bin/rails r 'EmbeddedAnsible.stop'
  • Enable the role in the UI

Here, instead of enabling the role first, I use the console to start the service which runs the first initial setup, but does not try to do anything that would be prevented because you don’t have a licence. Then you can licence the installation without having to deal with a “window” of opportunity, then shut it down and use it as designed as a role in the UI.

This will not give you access to the Tower UI, but again, that was intended.
If you want to use fully-fledged tower I would suggest installing it separately and using the Tower provider integration rather than the embedded role.

I think a good enhancement would be to allow users to provide a licence file for use with embedded Ansible. Then I think we could provide that as part of the initial setup, preventing the user from having to do most, if not all, of this work.


#3

@carbonin is there an easy way to use an external tower instead of the embedded tower?

Like

  • enable embedded role
  • run EmbeddedAnsible.start
  • change auth and endpoints of embedded ansible to point to external tower

#4

Why not simply setup an Ansible Tower provider ?


#5

Thats more for development, I think both also differ feature wise.

Here is some sample code

    provider = ManageIQ::Providers::EmbeddedAnsible::Provider.first_or_initialize
    provider.name = "Embedded Ansible"
    provider.zone = MiqServer.my_server(true).zone
    provider.url  = URI::HTTPS.build(:host => server.hostname || server.ipaddress, :path => "/ansibleapi/v1").to_s
    provider.verify_ssl = 0
    provider.url  = "https://tower.example.com/api/v1/"
    provider.save
    provider.update_authentication(:default => {:userid => "admin", :password => "password"})
    provider.authentication_check
    EmsRefresh.refresh(provider.managers.first)

#6

The problem with that @durandom is that the worker will set the provider url at startup, so you will need to run that every time the embedded ansible worker starts. If you’re okay with that then this should do the job for one run of the server.

ref: https://github.com/ManageIQ/manageiq/blob/fc36cd5817ec9ce58828870911b8880691d3a5e6/app/models/embedded_ansible_worker/runner.rb#L49-L52


#7

I was able to get the Ansible Tower license file from https://www.ansible.com/license. The link https://www.ansible.com/tower-trial mentioned in the OP led me to download the software, which isn’t needed since we already installed ansible-tower-setup through yum


#8

In order to make embedded Ansible work this is what we’ve done. working with anageiq fine-2 release

cat > /etc/yum.repos.d/ansible-tower.repo << EOF
[ansible-tower]
name=Ansible Tower Repository - $releasever $basearch
baseurl=http://releases.ansible.com/ansible-tower/rpm/epel-7-$basearch
enabled=1
gpgcheck=0
EOF
cat > /etc/yum.repos.d/jlaska-rabbitmq.repo << EOF
[jlaska-rabbitmq]
name=Copr repo for rabbitmq owned by jlaska
baseurl=https://copr-be.cloud.fedoraproject.org/results/jlaska/rabbitmq/epel-7-$basearch/
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/jlaska/rabbitmq/pubkey.gpg
enabled=1
enabled_metadata=1
EOF
cat > /etc/yum.repos.d/pgdg-94-centos.repo <<EOF
[pgdg94]
name=PostgreSQL 9.4 $releasever - $basearch
baseurl=http://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-$releasever-$basearch
enabled=1
gpgcheck=0
EOF
yum -y install ansible-tower-setup ansible-tower-server
yum -y install sudo
install -o awx -g awx -m 0755 -d /var/log/tower
install -o awx -g awx -m 0644 /dev/null /var/log/tower/callback_receiver.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/fact_receiver.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/task_system.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower_rbac_migrations.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower_system_track_migrations.log
install -o awx -g awx -m 0644 /dev/null /var/log/tower/tower_system_tracking_migrations.log
vi /var/lib/awx/setup/roles/preflight/defaults/main.yml
minimum_var_space: 10000
vmdb
bin/rails r ‘EmbeddedAnsible.start; puts MiqDatabase.first.ansible_admin_authentication.password’
(ajouter la ligne « “eula_accepted”: true, » dans le fichier de license.json)
curl -k -u ‘admin:pwd’ https://localhost:54322/api/v1/config/ -X POST -H ‘Content-Type: application/json’ -d @/tmp/license.json
bin/rails r ‘EmbeddedAnsible.stop’

You’ll need to add sudo package only for containerized installation


#9

Could you explain a little bit more this code :

MiqDatabase.first.ansible_admin_authentication.password’
“this sentence give a password?”

“What , i have to do with this :”
(ajouter la ligne « “eula_accepted”: true, » dans le fichier de license.json)

"what pwd i have to put in this sentence?"
curl -k -u ‘admin:pwd’ https://localhost:54322/api/v1/config/ -X POST -H ‘Content-Type: application/json’ -d @/tmp/license.json

bin/rails r ‘EmbeddedAnsible.stop’

After that the Embebed Ansible option should be active to add repositories ?

Those are my screenshoot . I can`t see the problem . Could you help me?


#10

Now AWX is release. Can we use AWX instead of Ansible Tower?

  • AWX is open source version of Ansible Tower

#11

@teerawat
Now we need to promote MIQ team to bundle awx to appliance so special installation would not be required. I think there should be an issue on github.


#12

Hi Guys.

I created the issue please pay attention to it and help promote it.

https://github.com/ManageIQ/manageiq/issues/15975