# Managing Compute Instances with OCI Run Command and Ansible
This document provides a guide to writing Ansible playbooks that use version 5.5 of the Oracle Cloud Infrastructure (OCI) collection to manage and interact with OCI compute instances. Specifically, this guide focuses on using the oracle.oci.oci_compute_instance_agent_instance_agent_command module to execute commands on compute instances through the OCI Instance Agent. Using this method does not require the management SSH key pairs on your OCI compute instances, thus simplifying your configuration.
Note
To run privileged commands with Run Command on OCI the ocarun user must be given sudo permissions. See the section Running Privileged Commands below for more details
# On Linux:
sudo echo "ocarun ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/101-oracle-cloud-agent-run-command
# On Windows:
Add-LocalGroupMember -Group "Administrators" -Member "NT SERVICE\OCARUN" | Restart-Service -Name OCARUN -Force
# Understanding the Agent Command Modules
The oracle.oci.oci_compute_instance_agent_instance_agent_command module allows you to create and manage instance agent commands on OCI compute instances. This module leverages the OCI Instance Agent, which is a lightweight service that runs on compute instances and enables you to execute commands, manage plugins, and perform other management tasks without SSH access. For additional infomarion on OCI Run Command, see: https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/runningcommands.htm
# Checking Command Execution Status and Output
The oci_compute_instance_agent_instance_agent_command module creates and submits commands but returns immediately after creation. To check the execution status and retrieve command output, you need to use the oci_compute_instance_agent_instance_agent_command_execution_facts module.
# Basic Playbook Example
Here is a simple example of an Ansible playbook that runs a command on an OCI compute instance.
# Execute command on OCI compute instance
---
- hosts: localhost
gather_facts: false
vars:
compartment_id: "ocid1.compartment.oc1..example"
instance_id: "ocid1.instance.oc1.iad.example"
tasks:
- name: Run system update command
oracle.oci.oci_compute_instance_agent_instance_agent_command:
compartment_id: "{{ compartment_id }}"
instance_id: "{{ instance_id }}"
display_name: "System Update Command"
content:
source:
source_type: "TEXT"
text: |
#!/bin/bash
sudo yum update -y
echo "Update completed at $(date)"
execution_time_out_in_seconds: 600
register: command_result
- name: wait for command to complete
oracle.oci.oci_compute_instance_agent_instance_agent_command_execution_facts:
instance_id: "{{ cmdb360_ci['compute']['sourceId'] }}"
instance_agent_command_id: "{{ command_result.instance_agent_command.id }}"
register: command_status
until: command_status.instance_agent_command_executions[0].lifecycle_state not in ['ACCEPTED', 'IN_PROGRESS']
retries: 60
delay: 10
- name: fail if command failed
ansible.builtin.fail:
msg:
- "Command execution failed"
- "Output: {{ command_status.instance_agent_command_executions[0].content.text.splitlines() | default('No output') }}"
when: command_status.instance_agent_command_executions[0].lifecycle_state == 'FAILED'
- name: display command status
ansible.builtin.debug:
msg:
- "Command State: {{ command_status.instance_agent_command_executions[0].lifecycle_state }}"
- "Exit Code: {{ command_status.instance_agent_command_executions[0].content.exit_code | default('N/A') }}"
- name: display command output
ansible.builtin.debug:
msg: "{{ command_status.instance_agent_command_executions[0].content.text.splitlines() | default('No output') }}"
Note: Multiple commands may also be supplied on a single line separated by ‘\n’
# Access and Privileges
The credentail used for Run Command is an API key associated with associted to a user. That user needs the ‘manage instance-agent-command-family’ permission in compartments where the compute instances reside. Additionally, the compute instances on which the command is being run, need to belong to a Dynamic Group with the ‘use instance-agent-command-execution-family’ permission. See the following document for more information about configuring this access: https://docs.cmdb360.com/docs/Satellites/OCI-satellite/ConfigureOciAccess/ConfigureOciAccess
# Understanding and Configuring Agent Polling
The OCI Instance Agent operates on a polling mechanism where the agent periodically checks for new commands from the OCI service. By default, the Instance Agent polls for new commands approximately every 4 minutes. This polling interval can cause delays between when you submit a command and when it actually starts executing on the instance.
# Default Polling Behavior
When you create an instance agent command using the Ansible module, the following sequence occurs:
- The command is created in the OCI service and enters the ACCEPTED state
- The Instance Agent polls the OCI service on its regular interval (default: ~4 minutes)
- The agent discovers the new command and begins execution (state changes to IN_PROGRESS)
- The command executes on the instance
- The agent reports completion back to the OCI service (state changes to SUCCEEDED or FAILED)
This means there can be a several minute delay before your command starts executing, which is important to account for when planning automation workflows or setting timeout values.
# Adjusting the Polling Interval
You can reduce the polling interval to make the Instance Agent check for commands more frequently. This is configured directly on the compute instance by modifying the Run Command Agent configuration file.
# Configuration Steps
To adjust the polling interval on a Linux instance:
-
SSH into your compute instance or use a console connection
-
Check the current Run Command config file settings
sudo cat /etc/oracle-cloud-agent/plugins/runcommand/config.yml -
Edit the Run Command configuration file
sudo vi /etc/oracle-cloud-agent/plugins/runcommand/config.yml -
Modify the pollCommandInterval setting and save the changes
-
Restart the Instance Agent service
sudo systemctl restart oracle-cloud-agent
# Considerations and Recommendations
· Lower polling intervals (e.g., 30 seconds) result in faster command execution but increase API calls and agent overhead. This can cause issues with the Oracle Discovery Satellite’s ability to poll resources. Especially if a large number of compute instances have lowered polling intervals.
· API call limits are at the tenant level, thus all compute instance agents in the tenancy effect this limit
· Higher polling intervals (e.g., 5-10 minutes) are suitable for periodic maintenance tasks
· For time-sensitive operations, configure a 30-60 second polling interval
· Remember to account for the polling delay when setting execution_time_out_in_seconds in your playbooks
· Monitor system resources if you significantly reduce the polling interval on many instances
· Consider using different polling intervals for different instance groups based on their automation needs
# Running Privileged Commands
By default, the Run Command agent cannot execute privileged commands. The Compute Instance Run Command plugin runs as the ocarun user on both Linux and Windows. This user must be given the appropriate access in order to execute privileged commands. Several playbooks offered by CMDB-360 require this access and so it is highly recommended to grant this access to the ocarun user.
# On Linux:
To run privileged commands on a Linux machine using the OCI Run Command feature, you must grant sudo permissions to the ocarun user on the target instance. The ocarun user is the default user under which the Compute Instance Run Command plugin executes scripts on Linux instances. This is the mechanism that the oracle.oci.oci_compute_instance_agent_instance_agent_command module uses to run commands on the remote instance.
To grant grant sudo permissions to the ocarun user to run all commands with sudo without needing a password, SSH to the compute instance as a privileged user and create a sudoers file with the following command
sudo echo "ocarun ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/101-oracle-cloud-agent-run-command
Alternatively, you can list specific commands instead of allowing all commands for a more secure configuration. Consult the sudo man page for syntax details.
# On Windows:
To allow it to run privileged commands on a Windows instance, you need to add the ocarun user to the local Administrators group.
Run the following command in an elevated PowerShell session:
Add-LocalGroupMember -Group "Administrators" -Member "NT SERVICE\OCARUN" | Restart-Service -Name OCARUN -Force
You can apply this configuration either via cloudbase-init at instance launch time, or by connecting to the instance after launch and running it manually.
# Troubleshooting
# Polling Issues
If commands are not being picked up by the agent even after adjusting the polling interval:
· Verify the Instance Agent plugin is enabled in the OCI console (Instance Details > Oracle Cloud Agent tab)
· Check that the oracle-cloud-agent service is running:
sudo systemctl status oracle-cloud-agent
· Review agent logs for errors:
sudo journalctl -u oracle-cloud-agent.service -n 100
· Ensure the instance has network connectivity to OCI services
· Verify IAM policies allow the instance to access the Instance Agent API
· Try restarting the agent service after configuration changes
# Authentication Errors
Ensure your OCI configuration file has the correct credentials and that the API key has not expired. Verify that your user has the necessary IAM permissions in the compartment.
# Command Timeout
If commands consistently timeout, increase the execution_time_out_in_seconds value. Note that the module creates the command but may return before execution completes. Use oci_compute_instance_agent_instance_agent_command_facts to poll for command completion status. Consider breaking complex commands into smaller steps. Also remember that the Instance Agent polling interval (default 5 minutes) adds delay before command execution begins - configure a shorter polling interval for time-sensitive operations.
# Permission Denied Errors
Commands run as the ocarun user. Use sudo in your scripts for operations requiring elevated privileges. Ensure the sudoers configuration allows passwordless sudo for ocarun.
# Additional Resources
· OCI Instance Agent Documentation: https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/manage-plugins.htm
· Running Commands on an Instance: https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/runningcommands.htm
· Ansible Documentation: https://docs.ansible.com/
· Ansible OCI Collection: https://docs.oracle.com/en-us/iaas/tools/oci-ansible-collection/5.5.0/
# Conclusion
The oracle.oci.oci_compute_instance_agent_instance_agent_command module in the OCI Ansible collection provides a powerful and reliable way to manage OCI compute instances through Ansible automation. By leveraging the Instance Agent, you can execute commands, deploy configurations, and manage your infrastructure without the complexity of SSH key management or direct network access.
As you develop your Ansible playbooks, remember to follow best practices for security, error handling, and idempotency. Start with simple commands and gradually build more complex automation workflows as you become familiar with the module’s capabilities and limitations. The Ansible OCI collection makes it easier than ever to build robust, production-ready automation for your OCI infrastructure.