I'm trying to write an ansible role that first does a docker login to a GCE instance before pulling images from the container registry. I need to do this because of the problem mentioned here.
First I tried the code block below
- name: Docker Login
docker_login:
registry: https://eu.gcr.io
username: _json_key
debug: true
password: "{{ lookup('file', 'pulse-psg-863d9955d8a1.json')}}"
The error I get with this is (private key modified)
fatal: [en1-a-sftp-delivery-0]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"api_version": null,
"cacert_path": null,
"cert_path": null,
"config_path": "~/.docker/config.json",
"debug": true,
"docker_host": null,
"email": null,
"filter_logger": false,
"key_path": null,
"password": "{'private_key': '-----BEGIN PRIVATE KEY-----\\vU5K1MuTpTQGEzg\\nuywOlHw7ZLEj4u65vxrnzpiCOw6Pu7IVZq9R2JPhAoGAFnpxIA4RxuB7cRIOU6EY\\naqBaHT73gmw8ulCHYSUWw+/P9ZquFjsnF8p7hzZ8pCOMSUwaLCQaDfqZvfcEoMqI\\naz9cOJdyjsZjOb1DLd2YtLCUNWldu5Nmh621L51bNh+clYpiSwOnD+ZhN5jrkIK9\\nleeCdUVeg71+h2gzKJGHJBU=\\n-----END PRIVATE KEY-----\\n', 'private_key_id': '********', 'token_uri': '********', 'auth_provider_x509_cert_url': '********', 'auth_uri': '********', 'client_email': '********', 'client_id': '********', 'project_id': '********', 'type': '********', 'client_x509_cert_url': '********'}",
"reauthorize": false,
"registry": "https://eu.gcr.io",
"registry_url": "https://eu.gcr.io",
"ssl_version": null,
"state": "present",
"timeout": null,
"tls": null,
"tls_hostname": null,
"tls_verify": null,
"username": "_json_key"
}
},
"msg": "Logging into https://eu.gcr.io for user _json_key failed - 500 Server Error: Internal Server Error (\"{\"message\":\"Get https://eu.gcr.io/v2/: unknown: Unable to parse json key.\"}\")"
}
I couldn't for the life of me get it to parse the private key. I suspect it's got something to do either with the asterisk characters (I don't know if that's only ansible masking it in the debug output or whether that's what is being sent onwards) or the \n character.
I tried therefore to login to the GCE machine and try the command from the command line as shown in the second answer here. So first I scp'd the keyfile onto the machine and then:
JSON_KEY=$(cat keyfile.json)
sudo docker login -u _json_key -p "$JSON_KEY" https://gcr.io
This worked with a few warnings but I was able to login and pull images thereafter. I concluded that it's an issue with the docker login ansible module and so decided to try a shell command instead. So:
- name: Docker Login using shell
shell: docker login -u _json_key -p "{{ lookup('file', 'keyfile.json') | replace('\n', '')}}" http://eu.gcr.io
This does not succeed either
snip
"module_args": {
"_raw_params": "docker login -u _json_key -p \"{\n \"type\": \"service_account\",\n \"project_id\": \"id\",\n \"private_key_id\": \"863d9955d8a1e5e04a15b36ef80a787bc2\",\n \"private_key\": \"-----BEGIN PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2Z7c33lnCQDXFssGvg0t9xi9Aqk6x4cazQPUJ8j0Y+qWDBPL+ShHNSZwVykmAugC51KKInm5ik4IWTA5ict3VBRnWiutdxQK++icZ2yCuFlPMDFp2g2GQ4wl8bH1X3AtWgHO/nSWD3Rle7M/p9CUJq3K1EA07H9GKBJZmfGaoc4HA+OG8/j2Q7i8KmG9pFjKOAlQsHPdKKZqn4YeHPOTmARJgxw6PXbchAp+nPA7f7hpbmaK3XRNRxuB7cRIOU6EYaqBaHT73gmw8ulCHYSUWw+/P9ZquFjsnF8p7hzZ8pCOMSUwaLCQaDfqZvfcEoMqIaz9cOJdyjsZjOb1DLd2YtLCUNWldu5Nmh621L51bNh+clYpiSwOnD+ZhN5jrkIK9leeCdUVeg71+h2gzKJGHJBU=-----END PRIVATE KEY-----\",\n \"client_email\": \"duh-compute@developer.gserviceaccount.com\",\n \"client_id\": \"1115155168041\",\n \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n \"token_uri\": \"https://oauth2.googleapis.com/token\",\n \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/879255832886-compute%40developer.gserviceaccount.com\"\n}\" http://eu.gcr.io",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
msg": "non-zero return code",
"rc": 1,
"start": "2019-07-29 18:31:55.246592",
"stderr": "\"docker login\" requires at most 1 argument.\nSee 'docker login --help'.\n\nUsage: docker login [OPTIONS] [SERVER]\n\nLog in to a Docker registry",
"stderr_lines": [
"\"docker login\" requires at most 1 argument.",
"See 'docker login --help'.",
"",
"Usage: docker login [OPTIONS] [SERVER]",
"",
"Log in to a Docker registry"
],
SNIP
This again I suspect is because it does not like the format of the key but this time it's the docker login command rather than the remote server (as in the earlier case) where atleast the key was transmitted. In both cases the challenge seems to be to get a key stored in JSON format in a file transmitted without any extra characters as one would do when one refers to the environment variable when running the command directly on the command line.
I've spent the better part of 3 days now trying to automate having a GCE instance and making it work with docker something that should be fairly trivial.