Ansible is an excellent helper to create or edit a file with multiple lines. These lines are called a "block", hence the name blockinfile for the relevant module.
However in combination with PHP files you need to pay special attention to the blockinfile module and it's parameters.
In this particular situation, an Ansible playbook to deploy a PHP application was created. This PHP application supports an automated setup through the command line, by using a prepared config file (config.php). The following Ansible task was created which would create this config.php file with the needed content:
- name: Application Setup - Create app config config.php
blockinfile:
path: "{{ documentroot }}/config.php"
create: true
owner: "{{ user }}"
group: "{{ user }}"
block: |
<?php
$dbconfig = array(
'host' => 'localhost',
'port' => '3306',
'name' => '{{ database }}',
'user' => '{{ dbuser }}',
'password' => '{{ dbpass }}',
);
So far so good, the Ansible task ran through and created the file:
TASK [Application Setup - Create app config config.php] ****************************************************************
changed: [target]
But the task executing the actual setup on the command line (using Ansible command) failed with an error:
Failed to start the session because headers have already been sent by \"/var \n /www/example/app/config.php\" at line 1.
The error message is pretty clear (for someone having run into headers already sent error in the past). A closer look at the config.php file shows that on line 1 a non-PHP code is showing up:
root@target:~# cat /var/www/example/config.php
# BEGIN ANSIBLE MANAGED BLOCK
<?php
$dbconfig = array(
'host' => 'localhost',
'port' => '3306',
'name' => 'example',
'user' => 'example',
'password' => 'eedo3LisaiFoong',
);
# END ANSIBLE MANAGED BLOCK
The "# BEGIN ANSIBLE MANAGED BLOCK" string on line 1 (known as the "marker" in the blockinfile module) causes problems here.
To solve this, we can adjust the marker parameters of the blockinfile module.
Note: An empty marker (marker: "") won't work, as this would create a newline at the beginning of the PHP file, leading to the same error.
To use a correct marker for a PHP file, here's a quick reminder how comments are made inside PHP code:
// for a single line comment in PHP
/* for a
multi line
comment in PHP /*
With this knowlege we can adjust the blockinfile task and adjust the marker_begin to start with the PHP context (<?php) followed by the BEGIN comment. The marker_end simply shows a PHP comment marking the END of the Ansible block but could also contain a closing PHP context (?>). But as you might know this is not necessary in PHP. This results in the following modified blockinfile task:
- name: Application Setup - Create app config config.php
blockinfile:
path: "{{ documentroot }}/config.php"
create: true
create: true
owner: "{{ user }}"
group: "{{ user }}"
marker: "{mark} ANSIBLE MANAGED BLOCK"
marker_begin: "<?php // BEGIN"
marker_end: "// END"
block: |
$dbconfig = array(
'host' => 'localhost',
'port' => '3306',
'name' => '{{ database }}',
'user' => '{{ dbuser }}',
'password' => '{{ dbpass }}',
);
This results in the following final file config.php:
root@irczsrvc49:~# cat /var/www/example/config.php
<?php // BEGIN ANSIBLE MANAGED BLOCK
$dbconfig = array(
'host' => 'localhost',
'port' => '3306',
'name' => 'example',
'user' => 'example',
'password' => 'shaeh7Pohz4cie5',
);
// END ANSIBLE MANAGED BLOCK
Now that this config.php is a valid PHP file (without any lines outside the PHP context), the setup task using /usr/bin/php completed successfully without errors.
No comments yet.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder