Roots Discourse

Interactive console authentication for 3rd party repository on deploy

#1

Hey there!

I’ve got a multisite subdomain installation that I’ve been working on migrating to a trellis set up for some time.

I’ve added this 3rd party composer repository to composer.json so I can just require these plugins directly from wpmudev:

{
  "type": "composer",
  "url": "https://premium.wpmudev.org"
}

Which is great, but they require some authentication with API key.

I was able to get it working on development and staging, but I keep getting this error when deploying to production:

...URL required authentication. You must be using the interactive console to authenticate install.

So with the deploy half done, theres no symlinked current folder yet, I tried to run composer directly on the production machine from the /shared/source/site/ directory but that ends up throwing other errors related to other vendor files not being there.

How do I authenticate this repository so my deploy won’t error out?

0 Likes

#2

I was hoping a wpmu dev free trial would let me test a solution for you, but wpmu points out that “this [composer] feature is not available to members on our 14-day trial” (ref). Rather than pay $49 USD to test, I’ll just post what I would have tried. I haven’t tested the tasks or templates below, so they may need some tweaking.

Presumably the presence of an auth.json will skirt around the interactive console requirement (see related composer docs and wpmu members-only mention of auth.json).

I’d add your wpmu dev API key to one of your group_vars/<environment>/vault.yml files. Suppose you use the same key for all environments and all sites. In such a case you could add the key to group_vars/all/vault.yml:

  # Documentation: https://roots.io/trellis/docs/vault/
  vault_mail_password: smtp_password
+ vault_wpmudev_api_key: 6wvmdak7kkdrmzcaygqyat2x9y57s2q8dpfxfzh9

Then I’d add a template task to deploy-hooks/build-before.yml:

- name: Create compose auth.json for wpmu dev
  template:
    src: "{{ playbook_dir }}/deploy-hooks/auth.json.j2"
    dest: "/home/{{ ansible_user }}/.composer/auth.json"
    mode: "0600"

Then I’d create the deploy-hooks/auth.json.j2 template on my local machine in my trellis project :

{
    "http-basic": {
        "premium.wpmudev.org": {
            "username": "{{ vault_wpmudev_api_key }}",
            "password": ""
        }
    }
}

Now, each deploy should create the auth.json before the composer install, if it isn’t already there.


In case you need to use a different API key per site and per environment, you could add the key to vault_wordpress_sites instead:

  vault_wordpress_sites:
    example.com:
+     wpmudev_api_key: 6wvmdak7kkdrmzcaygqyat2x9y57s2q8dpfxfzh9
      env:
        db_password: example_dbpassword
        ...

In that case, your deploy-hooks/auth.json.j2 would need an adjustment like this:

- "username": "{{ vault_wpmudev_api_key }}",
+ "username": "{{ vault_wordpress_sites[site].wpmudev_api_key }}",

An alternative would be to go ahead and allow interactions instead of trying to skirt them via the auth.json above.

This would be a more involved implementation of Trellis deploy hooks. You could try replacing the deploy_build_after definition to reference your own version of the hooked file.

- deploy_build_after: "{{ playbook_dir }}/roles/deploy/hooks/build-after.yml"
+ deploy_build_after: "{{ playbook_dir }}/deploy-hooks/build-after.yml"

You’d copy roles/deploy/hooks/build-after.yml to a new file at deploy-hooks/build-after.yml then replace the composer task with a task using Ansible’s expect module, where the command is a manual composer install command.

5 Likes

#3

This worked like a charm. Thanks so much. Not sure how I missed that wpmudev thread.

1 Like

#4

I had to create the .composer directory first:

- name: Create composer directory
  file:
    path: "/home/{{ ansible_user }}/.composer"
    state: directory
    owner: "{{ web_user }}"
    group: "{{ web_group }}"
    mode: 0775
0 Likes

#5

You can try and do it more simple with a composer task:

- name: Setup premium.wpmudev.org authentication
  composer:
    global_command: yes
    command: config
    arguments: http-basic.premium.wpmudev.org {{ vault_wpmudev_api_key }} ""
  when: vault_wpmudev_api_key is defined
3 Likes

#6

Nice one. Thanks for sharing!

0 Likes

#7

Thank you @fullyint @pacotole, I have applied something similar for Yoast Premium:

Add to group_vars/all/vault.yml
vault_yoast_premium_token: xxx

Then in deploy_hooks/build-before.yml, before ‘Install Composer dependencies’

- name: Register Yoast premium token
   composer:
    global_command: yes
    command: config
    arguments: http-basic.my.yoast.com token {{ vault_yoast_premium_token }}
   when: vault_yoast_premium_token is defined
0 Likes

#8

Some trouble implementing this, not sure if it could be because it’s an older install of Trellis or not.

My build-before.yml

...

- name: Create auth.json for Delicous Brains Plugins
  template:
    src: "{{ playbook_dir }}/deploy-hooks/auth.json.j2"
    dest: "/home/{{ ansible_user }}/.composer/auth.json"
    mode: "0600"

- name: Install Composer dependencies
  command: composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader --no-scripts
  args:
    chdir: "{{ deploy_helper.new_release_path }}/web/app/themes/sage"
  
  ...

This is my auth.json.j2 file (residing in deploy-hooks)

{
    "http-basic": {
        "composer.deliciousbrains.com": {
            "username": "{{ vault_deliciousbrains_api_username }}",
            "password": "{{ vault_deliciousbrains_api_password }}"
        }
    }
}

(Keys are present in the group_vars/all/vault.yml)

When trying to deploy to my stage env I got this error message:

IOError: [Errno 2] No such file or directory:

u'/Users/my.user/WWW/myproject.tld/trellis/deploy-hooks/auth.json.j2'

fatal: [63.32.106.101]: FAILED! => {"changed": false, "failed": true}

Any ideas? Issue with the playbook_dir var?
0 Likes

#9

Not sure about the playbook_dir variable but you might have better luck using @pacotole’s solution. It does the same thing without the need for the .json file.

0 Likes

#10

Right, any idea on how to reference multiple tokens? As there are both user/password to access the composer api for Delicious Brains plugins.

Edit: Btw, also getting this warning, not sure if it’s significant
NO MORE HOSTS LEFT *************************************************************
[WARNING]: Could not create retry file 'deploy.retry'. [Errno 2] No such file or directory: ''

0 Likes

#11

Gah!

There was unintended white space after .j2 in the file name of the template file, silly! :see_no_evil:
Maybe it’ll help some poor person in the future :slight_smile:

1 Like