I (strongly) believe that Ansible roles should not have any dependencies. It should rely on defaults which should be overridden when calling the role from your playbook. There are, however, situations where a default makes no sense. In those situations, I add a check for required variables as follows:

First, create a list of required variables in vars/main.yml like this:

---
  # src: vars/main.yml
  required_variables:
    - s3_website_domain

Note: why vars/main.yml I hear you ask? Well, this way you can’t override the value of the required_variables variable ;)

Now, you can check if those defined variables are defined and actually have a value using this construct:

- fail:
    msg: "No value specified for '{{ item }}'"
  when: ({{ item }} is undefined) or ({{ item }} is defined and {{ item|trim == '' }})
  with_items: required_variables

In your playbook, call your role as follows:

---
    ...
    roles:
      - role: hugo-aws-infra
        s3_website_domain: foobar-it.com
        tags: infra
    ...

When you don’t specify a value for, in this case, s3_website_domain, you’ll see something like this:

failed: [localhost] (item=s3_website_domain) => {"failed": true, "item": "s3_website_domain", "msg": "No value specified for 's3_website_domain'"}

It fails, just like it should …