├── LICENSE ├── README.md └── screenshots ├── create_custom_module_file.PNG ├── create_project.PNG ├── py_charm_debugger_new_configuration.PNG ├── py_charm_debugger_prompt.PNG ├── pycharm_breakpoint_set.PNG ├── pycharm_debug_icon.PNG ├── pycharm_debug_server.PNG ├── pycharm_debug_variables.PNG └── pycharm_new_remote_debugger.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Mumshad Mannambeth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Introduction 2 | I have been developing custom [Ansible](https://www.ansible.com/) modules on my windows system using [JetBrains PyCharm IDE](https://www.jetbrains.com/pycharm/). Below I describe some challenges and best practices on the development and how to debug remotely. 3 | 4 | For information about developing custom modules using Ansible check [here](http://docs.ansible.com/ansible/developing_modules.html). 5 | 6 | ## Challenge 7 | Though Ansible supports configuring Windows systems, Ansible itself [cannot](http://docs.ansible.com/ansible/intro_windows.html#reminder-you-must-have-a-linux-control-machine) be run on a windows control machine. If you are developing custom Ansible modules on a Windows Machine you might find it difficult to debug. This can be difficult if you are used to debugging in the IDE. The [test-module](https://github.com/ansible/ansible/blob/devel/hacking/test-module) offers some debug options if you are good with debugging in the Linux console. 8 | 9 | In this article I explain how to debug using the IDE debugger on a windows system by running the module remotely on a Ansible controller Linux system. 10 | 11 | ### Development Environment Setup and Pre-requisites 12 | Below is my development environment: 13 | * Development system - Windows 7 14 | * Development IDE - [JetBrains PyCharm IDE](https://www.jetbrains.com/pycharm/) Professional Edition * 15 | * Ansible Controller - OpenSuse Linux Machine with Ansible installed. Must have network connectivity with the Development Windows System. 16 | * Must have the Ansible devel package downloaded on the Linux Controller Machine to test custom modules - [test-module](https://github.com/ansible/ansible/blob/devel/hacking/test-module). For instructions on setting this up, please see [Installation](http://docs.ansible.com/ansible/intro_installation.html). 17 | 18 | >\* Must have a [JetBrains PyCharm Professional Edition](https://www.jetbrains.com/pycharm/download) for remote debugging features. Community edition [does not](https://www.jetbrains.com/pycharm/features/) support remote debugging. If you have not purchased already You can get a free trial of Professional Edition for 30 days. 19 | 20 | ### Develop Custom Ansible Module 21 | 22 | Create a new project in JetBrains PyCharm and create a new file in the project named - 'OSCheckModule.py' 23 | 24 | If you have never developed a custom Ansible module, start [here](http://docs.ansible.com/ansible/developing_modules.html). 25 | Start from the Common base template and build your module. Here I have a custom module called **OSCheckModule** that checks the OS flavor against a given input : 26 | 27 | ```python 28 | #!/usr/bin/python 29 | 30 | try: 31 | import json 32 | except ImportError: 33 | import simplejson as json 34 | 35 | import os 36 | 37 | DOCUMENTATION = ''' 38 | --- 39 | module: OSCheckModule 40 | short_description: A custom module to check OS of target machine. 41 | description: 42 | - A custom module to check OS of target machine. 43 | options: 44 | os_name: 45 | description: 46 | - Name of OS to check 47 | required: true 48 | ''' 49 | 50 | EXAMPLES = ''' 51 | # Example 52 | module_name: 53 | os_name: Linux 54 | ''' 55 | 56 | 57 | def main(): 58 | module = AnsibleModule( 59 | argument_spec=dict( 60 | os_name=dict(required=True), 61 | ) 62 | ) 63 | 64 | # Retreive parameters 65 | os_name = module.params['os_name'] 66 | 67 | # Check for OS 68 | if os_name in os.uname(): 69 | # Successfull Exit 70 | module.exit_json(changed=True, msg="OS Match") 71 | else: 72 | # Fail Exit 73 | module.fail_json(msg="OS Mismatch. OS =" + os.uname()[0]) 74 | 75 | 76 | from ansible.module_utils.basic import AnsibleModule 77 | 78 | if __name__ == '__main__': 79 | main() 80 | ``` 81 | 82 | We are ready with our first custom module. We will now copy this fiel to our Linux Controller Machine for execution. We can use PyCharm's remote Python interpretor feature to push and run the script remotely on the Linux Controller machine without having to manually copy over. Read about it [here](https://www.jetbrains.com/help/pycharm/2016.1/configuring-remote-python-interpreters.html). Will blog about it another time. 83 | 84 | ### Executing Custom Ansible Module 85 | 86 | I have copied my new module file to the path `/opt/ansible/custom_modules` in my Linux Ansible Controller Machine. I can now use the [test-module](https://github.com/ansible/ansible/blob/devel/hacking/test-module) to test and execute my new custom ansible module. 87 | 88 | Syntax: 89 | ``` 90 | /opt/ansible/ansible-devel/hacking/test-module -m -a 91 | ``` 92 | 93 | Example: 94 | 95 | ``` 96 | root:/opt/ansible/custom_modules # /opt/ansible/ansible-devel/hacking/test-module -m OSCheckModule.py -a os_name=Linux 97 | * including generated source, if any, saving to: /root/.ansible_module_generated 98 | * this may offset any line numbers in tracebacks/debuggers! 99 | *********************************** 100 | RAW OUTPUT 101 | 102 | {"msg": "OS Match", "invocation": {"module_args": {"os_name": "Linux"}}, "changed": true} 103 | 104 | 105 | *********************************** 106 | PARSED OUTPUT 107 | { 108 | "changed": true, 109 | "invocation": { 110 | "module_args": { 111 | "os_name": "Linux" 112 | } 113 | }, 114 | "msg": "OS Match" 115 | } 116 | 117 | ``` 118 | 119 | Wow!! we have successfully created and tested our first Custom Ansible Module. 120 | 121 | ### Debugging Custom Ansible Module 122 | 123 | We would now like to debug our custom ansible module using PyCharm debugger. For example we would like to set a break point at Line 46 to inspect the result of os.uname() call. We wouldwill use Python [pydevd](https://pypi.python.org/pypi/pydevd) for this purpose. 124 | 125 | #### Install pydevd on the Linux Machine Controller 126 | 127 | ``` 128 | pip install pydevd 129 | ``` 130 | 131 | #### Setup PyCharm Debug Server 132 | Create a new Project in PyCharm and go to **Run -> Edit Configurations..** 133 | 134 | Click on the plus sign in top left corner and select Python Remote Debug. (You must be using PyCharm Professional Edition to have this feature. Ths is not available in PyCharm Community Edition.) 135 | 136 | ![remote debugger](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/pycharm_new_remote_debugger.png) 137 | 138 | Provide the following information : 139 | * **Name**: Give a name to the debugger - OSCheckModule_Debugger 140 | * **Local host name**: Enter the IP of the Windows development system. Make sure you can ping and establish connectivity to this IP from your Linux System 141 | * **Port** - Set port to 54654 142 | * Path mappings - Ignore 143 | * Leave the remaining settings to default 144 | 145 | ![remote debugger configuratin](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/py_charm_debugger_new_configuration.PNG) 146 | 147 | Start the PyCharm Debug server by clicking on the debug optionbutton in the top right corner 148 | 149 | ![debug button](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/pycharm_debug_icon.PNG) 150 | 151 | The Debug server starts and starts listening for connections 152 | 153 | ![debug server](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/pycharm_debug_server.PNG) 154 | 155 | Note down the instructions provided to configure source code: 156 | ``` 157 | Use the following code to connect to the debugger: 158 | import pydevd 159 | pydevd.settrace('10.123.12.214', port=54654, stdoutToServer=True, stderrToServer=True) 160 | ``` 161 | 162 | #### Configure source code: 163 | 164 | Insert the following lines in the source code of the custom module - OSCheckModule.py 165 | 166 | Insert import pydevd line at the top 167 | ``` 168 | import pydevd 169 | ``` 170 | 171 | Insert the below line to set breakpoint at line 46 172 | 173 | ``` 174 | pydevd.settrace('10.123.12.214', port=54654, stdoutToServer=True, stderrToServer=True) 175 | ``` 176 | 177 | #### Start debugging 178 | 179 | Copy the source code to the linux system, if you have made the changes on your windows system. Run the module using test-module: 180 | 181 | ``` 182 | root:/opt/ansible/custom_modules # /opt/ansible/ansible-devel/hacking/test-module -m OSCheckModule.py -a os_name=Linux 183 | ``` 184 | 185 | If connectivity is established between the Linux and Windows systems, a prompt will appear in PyCharm in windows. 186 | 187 | ![debug server prompt](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/py_charm_debugger_prompt.PNG) 188 | 189 | Select the **Download Source** option to downlaod the source code to windows machine. The source will be downloaded the breakpoint is set. You can line step through the remainder of the code and use Debug console to view variables and their values. 190 | 191 | ![debug server console](https://github.com/mmumshad/debug-ansible-modules-pycharm/blob/master/screenshots/pycharm_debug_variables.PNG) 192 | 193 | Thank you for reading. Please feel free to comment, propose better solutions. 194 | 195 | 196 | ### Authors and Contributors 197 | Mumshad Mannambeth (@mmumshad) 198 | 199 | ### Support or Contact 200 | See a problem, have an issue? Raise an issue at the [github page](https://github.com/mmumshad/debug-ansible-modules-pycharm) 201 | -------------------------------------------------------------------------------- /screenshots/create_custom_module_file.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/create_custom_module_file.PNG -------------------------------------------------------------------------------- /screenshots/create_project.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/create_project.PNG -------------------------------------------------------------------------------- /screenshots/py_charm_debugger_new_configuration.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/py_charm_debugger_new_configuration.PNG -------------------------------------------------------------------------------- /screenshots/py_charm_debugger_prompt.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/py_charm_debugger_prompt.PNG -------------------------------------------------------------------------------- /screenshots/pycharm_breakpoint_set.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/pycharm_breakpoint_set.PNG -------------------------------------------------------------------------------- /screenshots/pycharm_debug_icon.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/pycharm_debug_icon.PNG -------------------------------------------------------------------------------- /screenshots/pycharm_debug_server.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/pycharm_debug_server.PNG -------------------------------------------------------------------------------- /screenshots/pycharm_debug_variables.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/pycharm_debug_variables.PNG -------------------------------------------------------------------------------- /screenshots/pycharm_new_remote_debugger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmumshad/debug-ansible-modules-pycharm/8075b256da838ca578cf83083df2cf2bfa667590/screenshots/pycharm_new_remote_debugger.png --------------------------------------------------------------------------------