Custom Connection Plugins - A new one: AWS Run Command

Hi everyone,

I’ve been working on a custom connection plugin to be used with AWS Run Command, allowing Ansible to be run natively on AWS instances that have the SSM agent installed and the proper IAM permissions/roles assigned. The major benefit of this for us is that internally we are using the SSM agent everywhere, and I no longer need to have access to the instance via SSH.

Aaaaanyway, I have a nice POC working beautifully with Ansible 2.0, and I am getting ready to port our plugin to Ansible 1.9, but it definitely looks like there was a ton of improvements made to connection plugins with v2.0.

Does anyone have any references on developing backwards compatible connection plugins?

Thanks,
Fran

PS: First post! Woot!

None right now, we are still waiting to write the documentation to port plugins from 1.9 to 2.0 …

Actually, I am working on implementing a custom HTTP connection plugin too. There are a lot of changes from 1.9 to 2.0 at the source code level, and I decided to implement my connection plugin on 2.0, which seems more object oriented.
Did you already implemented a ASW Run Command plugin on 1.9? What word should I do, if I want to write my own connection plugin? Would you share your experiences?

在 2016年4月26日星期二 UTC+8上午5:26:08,Fran Fitzpatrick写道:

Hi Sicheng,

I created my plugin first with 2.0 as a proof of concept (meaning I know it works by running it a few times; probably not ready for production). When I backported it to 1.9 (still as a POC; I’m working on getting it production ready now), it landed up not being that hard. Here’s the big things that I’ve seen so far (the diff is FROM_2.0 to TO_1.9):

NOTE: I don’t consider my work production ready, so… take it with a grain of salt. :stuck_out_tongue:

-from ansible.plugins.connection import ConnectionBase
-from ansible.utils.vars import combine_vars
+from ansible.callbacks import vv, vvv, vvvv, verbose # since Display doesn’t seem to be in 1.9

-try:

  • from main import display
    -except ImportError:
  • from ansible.utils.display import Display
  • display = Display()

-class Connection(ConnectionBase):
+class Connection(object):

And because there is no ConnectionBase apparently, gotta get rid of those super() calls.

  • def init(self, play_context, new_stdin, *args, **kwargs):
  • super(Connection, self).init(play_context, new_stdin,
  • *args, **kwargs)
  • def init(self, runner, host, port, user, password, *args, **kwargs):
  • def _connect(self):
  • def connect(self): # Looks like 1.9 needs a public connect method
  • def exec_command(self, cmd, in_data=None, sudoable=True):
  • ‘’’ run a command on the local host ‘’’
  • super(Connection, self).exec_command(cmd,
  • in_data=in_data,
  • sudoable=sudoable)
  • display.vvv(“EXEC length {}”.format(len(cmd)))
  • def exec_command(self, cmd, tmp_path=‘’, become_user=None, sudoable=False,
  • executable=None, in_data=None):

Hi all,

Just wanted to let you know that I’ve been making some great headway for this. Right now I have this connection plugin running on Linux hosts perfectly, and I have logic in the plugin to determine whether or not instance is Windows/Linux, dynamically determining whether or not to do “shell” things or “powershell” things.

However, I’m running into a problem with Windows. Even though my plugin has logic to determine whether or not an instance is Windows/Linux, the Ansible framework seems to always think it’s Linux. For example the first time the framework calls my exec_command() function [on a Windows machine], it passes the command: “mkdir <…> && chmod <…> && echo <…>”

What am I missing here? How do I let the framework know, or identify somewhere within my connection plugin, that I’m expecting powershelly type things?

Thanks,
Fran

So, it seems like what I was looking for was setting the .default_shell property. I landed up doing something like this, and things are now looking up:

@property
def default_shell(self):
if self.platform_type == ‘Windows’:
return ‘powershell’
else:
return ‘sh’

Hi Fran,

This sounds like quite a interesting option for me to look into, but unfortunately I am not a good enough developer to make something like this myself. Do you still have this plugin, and are you willing to share?

Thank you.

Regards,
Matt

Matt,

Yeah, definitely! I’m actually trying to get the entire plugin upstreamed, but blocked until this other PR gets merged: https://github.com/ansible/ansible/pull/25012

The plugin (awsrun) works really well right now, but it is very slow. I’m hoping that once we get it upstreamed, we’ll be able to work on some performance improvements to it, but we’re still at the mercy of the AWS APIs. :frowning:

Fran

Good to hear it’s still in business! I guess I’ll have to wait for the other work to be done

Thanks anyway!

Matt

Hi Fran,

Any good news for this nice plugin? Is it already in the upstream?

Hi Ting-Li,

I've actually changed jobs since working on this, and my current
employer doesn't really use AWS so I haven't even attempted to
upstream it.

Note: We did find some significant downsides to it, specifically AWS
rate limiting us by always asking "Hey, is it done yet? Hey, is it
done yet? Hey, is it done yet?" so I'd think there should probably be
some smarter way of handling getting the responses from Run Command
(Lambda? SNS?).

Fran