Deploy to multiple staging environments

Hi there,

I’m configuring my wordpress project with Trellis + Bedrock and I love it!

Very often, my team work in different branches in the same time and we need to test them, without have conflicts between us. So, the idea is have different staging sites, where we can test our branch independently, without quarrel of who can deploy to staging.

So, we want to can deploy the project to multiple staging environemnts, that is:

deploy site.com branch1 to staging1
deploy site.com branch2 to staging2

I already added the ability to tell the branch to deploy into the command, but my request now is: how can I specify different staging environemnts, but referring to the same WordPress site configuration of a staging env?

I hope is clear my request. Thanks in advice! :slight_smile:

I may not fully understand your question but it sounds like you may need more environment configs than just the staging and production configs that come with Trellis, is that correct?

If that’s what you need then you can simply copy trellis/group_vars/staging into trellis/group_vars/staging1 (you can call the new file anything you want). You also then need to copy trellis/hosts/staging to trellis/hosts/staging1 and site/config/environments/staging.php to site/config/environments/staging1.php.

Remember to actually open the copied files and rename any instances of staging to staging1 and configure them as needed (especially the hosts file).

Hope that helps.

2 Likes

I haven’t tried the ideas above, but the idea @cfx proposed sounds promising if you want your staging sites on different servers, as you seem to have indicated. If you add a new staging1 group to group_vars as suggested, I believe the implication would be that you also copy hosts/staging to hosts/staging1 and change the [staging] group name in the new file to [staging1].

New provision command: ansible-playbook server.yml -e env=staging1
New deploy command: ./bin/deploy.sh staging1 example.com (or whatever domain)


I suspect that a more common scenario would be that you want different sites to test different WordPress theme developments, not that you want different servers to test different server configs. In that case you could use a single staging server but deploy your different branches to different domains on the server. I have not tested the ideas below.

# group_vars/staging/wordpress_sites.yml

wordpress_sites:
  staging1.example.com
    site_hosts:
      - canonical: staging1.example.com
    repo: git@github.com:example/example.com.git
    branch: staging1
    ...
  staging2.example.com
    site_hosts:
      - canonical: staging2.example.com
    repo: git@github.com:example/example.com.git   # same repo as above
    branch: staging2
    ...

Then you could just list staging1.example.com and staging2.example.com in vault_wordpress_sites (in group_vars/staging/vault.yml) with all credentials repeated, or use a DRY modification like this:

# group_vars/staging/vault.yml
staging_example_com: 
  env:
    db_password: example_dbpassword
    # Generate your keys here: https://roots.io/salts.html
    auth_key: "generateme"
    secure_auth_key: "generateme"
    logged_in_key: "generateme"
    nonce_key: "generateme"
    auth_salt: "generateme"
    secure_auth_salt: "generateme"
    logged_in_salt: "generateme"
    nonce_salt: "generateme"

vault_wordpress_sites:
  staging1.example.com: "{{ staging_example_com }}"
  staging2.example.com: "{{ staging_example_com }}"

Your wordpress_sites indicates the correct branch so you won’t have to pass it as an option to your deploy command.
./bin/deploy.sh <environment> <site>
./bin/deploy.sh staging staging1.example.com
./bin/deploy.sh staging staging2.example.com

After deployment, you’d visit the sites/branches at their respective domains and find their files on the server at
srv/www/staging1.example.com
srv/www/staging2.example.com


For more alternatives and somewhat related Ansible options, see To deploy a second site

2 Likes

When I tried using the DRY method, I get this error, any ideas?

TASK [deploy : Copy project templates] ******************************************************************************
System info:
  Ansible 2.5.3; Darwin
  Trellis version (per changelog): "Update xdebug tunnel configuration"
---------------------------------------------------
AnsibleError: An unhandled exception occurred while templating '{{
wordpress_env_defaults | combine(project.env | default({}),
vault_wordpress_sites[site].env) }}'. Error was a <class
'ansible.errors.AnsibleFilterError'>, original message: |combine expects
dictionaries, got Undefined
failed: [staging_host] (item={u'dest': u'.env', u'src': u'roles/deploy/templates/env.j2', u'name': u'.env config'}) => {"changed": false, "item": {"dest": ".env", "name": ".env config", "src": "roles/deploy/templates/env.j2"}}
'{{wordpress_env_defaults | combine(project.env | default({}),
vault_wordpress_sites[site].env) }}'. Error was a <class
'ansible.errors.AnsibleFilterError'>, original message: |combine expects
dictionaries, got Undefined

I suspect you don’t have an env section in your base staging_example_com dictionary, so the attempt to merge env dictionaries fails because env is Undefined. See how env fits into this snippet from my post above…

# group_vars/staging/vault.yml
staging_example_com: 
  env:
    db_password: example_dbpassword
    # Generate your keys here: https://roots.io/salts.html
    [etc]

You’re welcome to paste some obfuscated version of your vault.yml file.

Still no luck, I can’t figure out what I’m missing. Not a huge deal, but just really curious.