SSH keys retrieval from Cyberark through AWX

,

We are the AWX team and are working on integrating SSH key management with CyberArk. Our goal is to extract an SSH private key and a CA-signed certificate from CyberArk, and use them as credentials in AWX to connect to Linux AWS servers.

The problem:
When we extract the SSH private key from CyberArk, the key comes as a string with \n characters (escaped newlines), which causes issues when using it as a credential in AWX/Ansible.
We need a reliable way to extract the private key and certificate from CyberArk, convert them to the correct format, and use them in AWX as SSH credentials.

Questions:

  1. What is the best way to process the CyberArk API response so that the SSH private key and certificate are in the correct format for use with AWX/Ansible?
  2. Are there any recommended Ansible modules or filters to handle this conversion automatically?
  3. Has anyone automated this workflow and can share best practices or example playbooks/script

Not sure if it helps or even applies to your situation, as I don’t use Cyberark, but when extracting SSH keys from the AWS Secrets Manager I have the same issue.

My solution was to use the Linux tool dos2unix.

Could you describe exactly how you’re doing it ?
Do you create a Machine Credential for your SSH Key and use the External Secret Management System functionality ?
Or do you use a lookup to pass the value to ansible_ssh_private_key_file ?
Are you using CyberArk CCP or Conjur ?

On our side, we created a custom credential to feed the EE with the necessary variable to reach Conjur, and then used the conjur_variable lookup to pass the value to ansible_ssh_private_key (using the as_file parameter). There are a few other things around that, but that’s the idea.

I use the shell to retrieve the key, pipe it through dos2unix and decode (as I store it base64 encoded) and then save to the file system.

This is my task:

- name: Retrieve private key using AWS CLI
  ansible.builtin.shell: >
    aws secretsmanager get-secret-value
    --secret-id ansible/private-key
    --output text
    --query SecretString
    | dos2unix
    | base64 --decode
    > {{ honorapps_sshkey }}
  no_log: "{{ not debug_mode }}"
  register: aws_secret_result
  retries: 2           # Number of attempts
  delay: 5            # Seconds between retries
  until: aws_secret_result.rc == 0  # Retry until command succeeds

The retries are kind of silly here, but I tend to add to most of my commands by default so left them here for consistency.

There is another task later on to delete the file when I am done.


- name: Remove key for git authentication
  ansible.builtin.file:
    path: "{{ honorapps_sshkey }}"
    state: absent

I am confident there are probably better ways to do this, but I am new to ansible and still learning new ways to do things every day.

I think that you could use the following lookup instead of relying on ansible.builtin.shell (which isn’t a great idea):
amazon.aws.secretsmanager_secret lookup – Look up secrets stored in AWS Secrets Manager — Ansible Community Documentation

You could directly pass the result in blockinfile or in a template for example. (but I think that it’s a bit off-topic, the post was specifically about AWX).

I do so in many scenarios, but the fact that lookups run on the host instead of the target was complicating things as I tried to build out a solution.

IIRC I needed to be able to specify the profile when I was running it from my computer, but then when running the script locally on the target (initial build of an auto scaling group replacement) the profile was breaking things.

I might circle back around to see if I can conditionally use the profile, but the complexity of that while trying to learn how to do everything else was too much for me to tackle all at once.

And I just realized that I need a better threaded view of the conversation because you were probably not responding to my post but the initial request.