I need to run ansible-playbook and output the run results to a json file, and also keep the normal stdout log.
In other words, keep the human readable log stream on stdout, but create a machine readable output to a file.
I can get ansible-playbook to output a json log by setting
[defaults]
log_path = /tmp/log.txt
stdout_callback = json
The problem is that this is overriding the stdout settings, so it doesn't output the "normal" job output text to stdout anymore.
Instead it dumps the json text after the run completes and also outputs the json to stdout.
What I'm looking for would be some sort of log_callback = json or log_callback = yaml type setting, and leaving stdout_callback default. However, nothing seems fit that while reviewing the available options.
Automated interaction with ansible has a dedicated library, ansible-runner
Related
I am writing a script that takes care of running a terraform file and create infra. I have requirement where I need to take output from the terraform into the same script to create schema for DB. I need to take Endpoint, username, Password and DB name and take it as an input into the script to login to the db and create schema. I need to take the output from aws_db_instance from terraform which is already created and push that as an input into the bash script.
Any help would be really appreciated as to how can we achieve this. thanks in advance. Below is the schema code that I would be using in script and would need those inputs from terraform.
RDS_MYSQL_USER="Username";
RDS_MYSQL_PASS="password";
RDS_MYSQL_BASE="DB-Name";
mysql -h $RDS_MYSQL_ENDPOINT -P $PORT -u $RDS_MYSQL_USER -p $RDS_MYSQL_PASS -D $RDS_MYSQL_BASE -e 'quit';```
The usual way to export particular values from a Terraform configuration is to declare Output Values.
In your case it seems like you want to export several of the result attributes from aws_db_instance, which you could do with declarations like the following in your root module:
output "mysql_host" {
value = aws_db_instance.example.address
}
output "mysql_port" {
value = aws_db_instance.example.port
}
output "mysql_username" {
value = aws_db_instance.example.username
}
output "mysql_password" {
value = aws_db_instance.example.password
sensitive = true
}
output "mysql_database_name" {
value = aws_db_instance.example.name
}
After you run terraform apply you should see Terraform report the final values for each of these, with the password hidden behind (sensitive value) because I declared it with sensitive = true.
Once that's worked, you can use the terraform output command with its -raw option to retrieve these values in a way that's more convenient to use in a shell script. For example, if you are using a Bash-like shell:
MYSQL_HOST="$(terraform output -raw mysql_host)"
MYSQL_PORT="$(terraform output -raw mysql_port)"
MYSQL_USERNAME="$(terraform output -raw mysql_username)"
MYSQL_PASSWORD="$(terraform output -raw mysql_password)"
MYSQL_DB_NAME="$(terraform output -raw mysql_database_name)"
Each run of terraform output will need to retrieve the latest state snapshot from your configured backend, so running it five times might be slow if your chosen backend has a long round-trip time. You could potentially optimize this by installing separate software like jq to parse the terraform output -json result to retrieve all of the values from a single command. There are some further examples in terraform output: Use in Automation.
I am trying to write a custom ansible module.
I need to have some debug info during module execution.
However the following lines fo not print anything even with the highest verbosity level enabled (-vvvv) and with export ANSIBLE_DEBUG=true
from ansible.module_utils.basic import AnsibleModule
module.log(msg="some_message"))
The only time I am ever able to see some msg printed is via the following method:
module.exit_json(changed=True, msg=_msg)
It should be emphasized that AnsibleModule.log() will not send the output to neither stout or stderr. It will send it to the default system logging facility.
In my case this was /var/log/syslog.
How can I make ansible show only errors inside of some playbook, or even when directly invoked?
I tried suppressing std output but that apparently didn't help, because execution errors seem to be put into standard output instead of error output on Linux.
ansible all -a 'some_command_I_want_to_know_if_it_crashes' 1> /dev/null
I see only errors from Python (exceptions etc.) but not errors from playbook (the red text).
Use the official sample callback plugin called actionable.py.
Put it in the callback_plugins directory and enable stdout-callbacks in ansible.cfg:
[defaults]
stdout_callback = actionable
Just by enabling it you will get much less information in th output, but you can further modify the plugin code to suit your needs.
For example to disable messages on successful tasks completely (regardless if status is ok or changed) change:
def v2_runner_on_ok(self, result):
if result._result.get('changed', False):
self.display_task_banner()
self.super_ref.v2_runner_on_ok(result)
to
def v2_runner_on_ok(self, result):
pass
As Konstantin Suvorov noted, the above ansible.cfg configuration method works for ansible-playbook.
For ansible output you can save the actionable.py as ./callback_plugins/minimal.py to achieve the same results.
You could run the command with actionable callback
ANSIBLE_STDOUT_CALLBACK=actionable ansible all -a 'some_command_I_want_to_know_if_it_crashes'
This is the contents of my .rspec_parallel file. I am using parallel_tests gem to run tests in multiple browser instances. To my knowledge, the gem uses the same formatter options available in RSpec.
--format html --out results<%= ENV['TEST_ENV_NUMBER'] %>.html
This works fantastic and I'm able to get the HTML output I normally see from RSpec. However, all of the 'puts' messages and basic standard output is logged to my console window, and not to the HTML files.
How can I get this output into each individual HTML file that I have set up?
puts will output to $stdout where as output is actually an instance variable of the RSpec::Core::Formatters::BaseFormatter class. output is defaulted to $stdout but when you pass in a string it determines that it should create a new StringIO and then output this to the given file name. Thus puts will not append to the #output variable.
You could do something ugly like create a runner file like
File.open('some_file_name.html','w+') do |file|
file << `rspec spec --format html`
end
Then this file will have the output from $stdoutbut your puts code will not be html formatted in this case. Other than that you could try building your own Custom Formatter but it will probably take quite a bit of source searching to make sure you can capture everything appropriately.
That being said it does seem the reporter was exposed for adding custom messages but I am uncertain of how to use this appropriately See Pull Request 1866
Seems it would be something like
it "has a name" do |ex|
ex.reporter.message("Custom Message Here")
#actual test
end
but the html formatter seems to ignore this. I can see the output in $stdout but not in the html file itself.
Best of luck.
I have a Capistrano deploy file (Capfile) that is rather large, contains a few namespaces and generally has a lot of information already in it. My ultimate goal is, using the Tinder gem, paste the output of the entire deployment into Campfire. I have Tinder setup properly already.
I looked into using the Capistrano capture method, but that only works for the first host. Additionally that would be a lot of work to go through and add something like:
output << capture 'foocommand'
Specifically, I am looking to capture the output of any deployment from that file into a variable (in addition to putting it to STDOUT so I can see it), then pass that output in the variable into a function called notify_campfire. Since the notify_campfire function is getting called at the end of a task (every task regardless of the namespace), it should have the task name available to it and the output (which is stored in that output variable). Any thoughts on how to accomplish this would be greatly appreciated.
I recommend not messing with the Capistrano logger, Instead use what unix gives you and use pipes:
cap deploy | my_logger.rb
Where your logger reads STDIN and STDOUT and both records, and pipes it back to the appropriate stream.
For an alternative, the Engineyard cap recipies have a logger – this might be a useful reference if you do need to edit the code, but I recommend not doing.
It's sort of a hackish means of solving your problem, but you could try running the deploy task in a Rake task and capturing the output using %x.
# ...in your Rakefile...
task :deploy_and_notify do
output = %x[ cap deploy ] # Run your deploy task here.
notify_campfire(output)
puts output # Echo the output.
end