How to replace a particular line in a file using ansible? - text

I want to use ansible to go to the nignx configuration file and and replace the ssl_certificate line with my own.
This is the line in nginx.conf
ssl_certificate "/etc/pki/nginx/server.crt";
All I want to know is what module and how do I use it to replace the path of the certificate to what I want.

Try below
- name: modify
replace:
path=/path/to/nginx.conf
regexp="^(ssl_certificate\s+)[^\n]+$"
replace="ssl_certificate \"/required/file/path/here\";"

To replace a particular line in a file using ansible you can use the lineinfile_module
- name: Replace a localhost entry with our own
lineinfile:
path: nginx.conf
regexp: '^ ssl_certificate "/etc/pki/nginx/server.crt";'
line: ' ssl_certificate "/your/path/server.crt";'
In my example I get this diff
< ssl_certificate "/etc/pki/nginx/server.crt";
---
> ssl_certificate "/your/path/server.crt";
But consider using the ansible role for NGINX .

Related

Shell script to replace all occurrnces of string with a value

I'm new to shell script.
I have a YAML file that consists of placeholder . I need to replace all the occurrences of placeholder <test-name> with a value sweta
script.sh
Name="sweta"
Below is the example of YAML file
metadata:
name: <test-name>-svc
namespace: abc
spec:
selector:
app: <test-name>
ports:
- protocol: TCP
name: http
port: 80
targetPort: 8080
My expected output is:
metadata:
name: sweta-svc
namespace: abc
spec:
selector:
app: sweta
ports:
- protocol: TCP
name: http
port: 80
targetPort: 8080
Can someone help me?
Appreciate all your help. Thanks in advance!
There are two easy ways to accomplish your search and replace <test-name> string with sweta
Note: Assuming your yaml file name is config.yaml
Option-1: Using stream editor command 'sed' as below:
To overwrite the original file
sed -i 's/<test-name>/sweta/g' config.yaml
To write the output to a different file
sed 's/<test-name>/sweta/g' config.yaml > updated_config.yaml
The syntax of sed command is sed -i 's/original/new/g' file.txt
where
sed is the command name
-i stands for in-place edit. This option is used to overwrite the original file. If you don't use this, you have to redirect output to a different file as done in second command above.
s stands for substitute
original is the search string
new is the replace string
g is for global (replace all occurrences). Omitting this will just replace only the first occurence
file.txt is the text file (Linux doesn't use extensions like .txt but people often name files with such extensions as a convention to denote file type)
Option-2: Use 'awk' command:
awk is a very powerful text processing command with its own language syntax, but this search and replace is quite easy:
awk '{gsub("<test-name>", "sweta"); print $0}' config.yaml > updated_config.yaml

Replace a single placeholder in a .conf file using bash

Hi everyone I am still learning bash at the moment but I am writing
a script for work that is being used to install Docker and CNTLM because we are running behind some proxies.
I have the installations working but am struggling to change 2 variable placeholders in the cntlm.conf file below.
cnlm.conf
#
# Cntlm Authentication Proxy Configuration
#
# NOTE: all values are parsed literally, do NOT escape spaces,
# do not quote. Use 0600 perms if you use plaintext password.
#
Username $MyUserName
Domain NTADMIN
Password $MyPassWord
# NOTE: Use plaintext password only at your own risk
# Use hashes instead. You can use a "cntlm -M" and "cntlm -H"
# command sequence to get the right config for your environment.
# See cntlm man page
# Example secure config shown below.
PassLM 93409221097752460192457192457999
PassNT 08992693829837928372938729387229
### Only for user 'testuser', domain 'corp-uk'
PassNTLMv2 02793865976487363876348763873467
# Specify the netbios hostname cntlm will send to the parent
# proxies. Normally the value is auto-guessed.
#
# Workstation netbios_hostname
I have been able to change the
PassLM
PassNT
PassNTLMv2
by using replace line with 'sed' but I am unable to change the $MyUserName and $MyPassWord from the variables being used in the bashscript.
Any ideas on how I can do this?
There are various alternatives:
To replace them using sed on a "template" and creating a new file, you can do it like this:
sed 's/\$MyPassword/MySuperPassword/' cnlm.conf > cnlm.new.conf
Now, if you will replace into the same file and you don't know the last value of the password, you can do:
sed -ri 's/^(Password *).*$/\1MySuperPassword/' cnlm.conf
If your new password is in a shell variable, then you can execute the last command like this:
newPasswd="abcde"
sed -ri "s/^(Password *).*$/\1${newPasswd}/" cnlm.conf
Finally, if you want to change the username and the password in the same command:
newUser="user123"
newPasswd="abcde"
sed -ri "s/^(Username *).*$/\1${newUser}/; s/^(Password *).*$/\1${newPasswd}/" cnlm.conf

Find and Replace value using SED

I have one file which contains key value pair
properties.env
development_port=8080
development_type=tcp
staging_port=8081
development_type=http
I need to read value from properties.env and replace it in another file based on some environment variable value lets say ENVIRONMENT=staging/development
config.yml
server:
adminConnectors:
-
port: 18001
type: http
The final output of config.yml should be if ENVIRONMENT=staging
server:
adminConnectors:
-
port: 8081
type: http
How can i achieve this using sed command?
Since the properties file looks like it has the right syntax you could just source it, and then replace the entire port line:
source properties.env
sed --in-place "s/port.*/port: $staging_port/" config.yml
This, of course, assumes the "port" line appears only once in your config.

Ansible uncomment line in file

I want to uncomment a line in file sshd_config by using Ansible and I have the following working configuration:
- name: Uncomment line from /etc/ssh/sshd_config
lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^#AuthorizedKeysFile'
line: 'AuthorizedKeysFile .ssh/authorized_keys'
However this config only works if the line starts by #AuthorizedKeysFile, but it won't work if the line starts by # AuthorizedKeysFile or # AuthorizedKeysFile (spaces between # and the words).
How can I configure the regexp so it won't take into account any number of spaces after '#'?
I've tried to add another lineinfile option with a space after '#', but this is not a good solution:
- name: Uncomment line from /etc/ssh/sshd_config
lineinfile:
dest: /etc/ssh/sshd_config
regexp: '# AuthorizedKeysFile'
line: 'AuthorizedKeysFile .ssh/authorized_keys'
If you need zero or more white spaces after the '#' character, the following should suffice:
- name: Uncomment line from /etc/ssh/sshd_config
lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^#\s*AuthorizedKeysFile.*$'
line: 'AuthorizedKeysFile .ssh/authorized_keys'
The modification to your original code is the addition of the \s* and the .*$ in the regex.
Explanation:
\s - matches whitespace (spaces, tabs, line breaks and form feeds)
* - specifies that the expression to it's left (\s) can have zero or more instances in a match
.* - matches zero or more of any character
$ - matches the end of the line
Firstly, you are using the wrong language. With Ansible, you don't tell it what to do, but define the desired state. So it shouldn't be Uncomment line form /etc/ssh/sshd_config, but Ensure AuthorizedKeysFile is set to .ssh/authorized_keys.
Secondly, it doesn't matter what the initial state is (if the line is commented, or not). You must specify a single, unique string that identifies the line.
With sshd_config this is possible as the AuthorizedKeysFile directive occurs only once in the file. With other configuration files this might be more difficult.
- name: Ensure AuthorizedKeysFile is set to .ssh/authorized_keys
lineinfile:
dest: /etc/ssh/sshd_config
regexp: AuthorizedKeysFile
line: 'AuthorizedKeysFile .ssh/authorized_keys'
It will match any line containing AuthorizedKeysFile string (no matter if it's commented or not, or how many spaces are there) and ensure the full line is:
AuthorizedKeysFile .ssh/authorized_keys
If the line were different, Ansible will report "changed" state.
On the second run, Ansible will find the AuthorizedKeysFile again and discover the line is already in the desired state, so it will end the task with "ok" state.
One caveat with the above task is that if any of the lines contains a comment such as a real, intentional comment (for example an explanation in English containing the string AuthorizedKeysFile), Ansible will replace that line with the value specified in line.
I should caveat this with #techraf's point that 99% of the time a full template of a configuration file is almost always better.
Times I have done lineinfile include weird and wonderful configuration files that are managed by some other process, or laziness for config I don't fully understand yet and may vary by distro/version and I don't want to maintain all the variants... yet.
Go forth and learn more Ansible... it is great because you can keep iterating on it from raw bash shell commands right up to best practice.
lineinfile module
Still good to see how best to configuration manage one or two settings just a little better with this:
tasks:
- name: Apply sshd_config settings
lineinfile:
path: /etc/ssh/sshd_config
# might be commented out, whitespace between key and value
regexp: '^#?\s*{{ item.key }}\s'
line: "{{ item.key }} {{ item.value }}"
validate: '/usr/sbin/sshd -T -f %s'
with_items:
- key: MaxSessions
value: 30
- key: AuthorizedKeysFile
value: .ssh/authorized_keys
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
validate don't make the change if the change is invalid
notify/handlers the correct way to restart once only at the end
with_items (soon to become loop) if you have multiple settings
^#? the setting might be commented out - see the other answer
\s*{{ item.key }}\s will not match other settings (i.e. SettingA cannot match NotSettingA or SettingAThisIsNot)
Still might clobber a comment like # AuthorizedKeysFile - is a setting which we have to live with because there could be a setting like AuthorizedKeysFile /some/path # is a setting... re-read the caveat.
template module
- name: Configure sshd
template:
src: sshd_config.j2
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: "0644"
validate: '/usr/sbin/sshd -T -f %s'
notify: restart sshd
handlers:
- name: restart sshd
service:
name: sshd
state: restarted
multiple distro support
And if you are not being lazy about supporting all your distros see this tip
- name: configure ssh
template: src={{ item }} dest={{ SSH_CONFIG }} backup=yes
with_first_found:
- "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.sshd_config.j2"
- "{{ ansible_distribution }}.sshd_config.j2"
https://ansible-tips-and-tricks.readthedocs.io/en/latest/modifying-files/modifying-files/
(needs to be updated to a loop using the first_found lookup)
Is it possible to achieve the same goal with replace module.
https://docs.ansible.com/ansible/latest/modules/replace_module.html
- name: Uncomment line from /etc/ssh/sshd_config
replace:
path: /etc/ssh/sshd_config
regexp: '^\s*#+AuthorizedKeysFile.*$'
replace: 'AuthorizedKeysFile .ssh/authorized_keys'
If you want to simply uncomment a line without setting the value, you can use replace with backreferences, eg (with a handy loop):
- name: Enable sshd AuthorizedKeysFile
replace:
path: /etc/ssh/sshd_config
# Remove comment and first space from matching lines
regexp: '^#\s?(\s*){{ item }}(.+)$'
replace: '\1{{ item }}\2'
loop:
- 'AuthorizedKeysFile'
This will only remove the first space after the #, and so retain any original indenting. It will also retain anything after the key (eg the default setting, and any following comments)
Thanks to the other helpful answers that provided a solid starting point.

add lines to the apache2 confing

I need to add this to my apache2.conf in my VPS:
Include /etc/phpmyadmin/apache.conf
extension=mysql.so
extension=memcache.so
extension=mbstring.so
extension=gd.so
extension=mcrypt
After I add this and save the apache.conf, and trying to restart the apache, i get an error - Failed.
Why?
You find that error because you put php directives in apache.
You have to add these lines in php.in file.
you can find php.ini file location using,
#php -i | grep php.ini

Resources