Portal:Cloud VPS/Admin/Service accounts

This page describes the current procedure/workflow/details that are required to create service accounts working on our CloudVPS (openstack) deployments.
Service accounts are user accounts intended to be used by scripts or any other kind of program or robots interacting automatically with the openstack APIs.
== Setup ==
The setup contains several steps:
* create the account as a normal user using Bitu or Striker, i.e, a standard LDAP user account.
* decide the privileges this account should have. There are mainly 2 options: projectadmin or designateadmin.
* add this new account to the project it should manage, with the appropriate role.
* add the user to the password safelist by keystone in the keystone.conf file.
* use the new user in your script!
== Known examples ==
=== Infrastructure user on Cloud VPS ===
Sometimes you need an user to be present in all virtual machine instances on Cloud VPS.
Creating a service account means the user will be stored in LDAP, thus present in all VMs.
The password for this account may be meaningless because the user will be used for SSH (and thus, the only important thing is the SSH key).
=== Interacting with the openstack API ===
The known examples to the date are DNS-related scripts that need to interact with the desginate API.
We have examples for the acme-chief mechanism in both the deployment-prep project and in the traffic project.
$ ldap cn=deployment-prep-dns-manager \* memberOf
dn: uid=deployment-prep-dns-manager,ou=people,dc=wikimedia,dc=org
uid: deployment-prep-dns-manager
sn: Deployment-prep-dns-manager
cn: Deployment-prep-dns-manager
objectClass: inetOrgPerson
objectClass: person
objectClass: ldapPublicKey
objectClass: posixAccount
objectClass: shadowAccount
uidNumber: 19091
gidNumber: 500
homeDirectory: /home/deployment-prep-dns-manager
loginShell: /bin/false
mail: krenair+betadnsmanager@<redacted>
memberOf: cn=project-deployment-prep,ou=groups,dc=wikimedia,dc=org
In the keystone.conf file:
[auth] 
methods = external,password,token,wmtotp 
 
# Override the default password plugin with a custom 
# one that checks source IPs. 
password = whitelist 
 
<% @labs_networks.each do |subnet| -%> 
password_whitelist = novaobserver:<%=subnet%> 
password_whitelist = deployment-prep-dns-manager:<%=subnet%> 
password_whitelist = traffic-cloud-dns-manager:<%=subnet%> 
<% end -%> 
<% @prod_networks.each do |subnet| -%> 
password_whitelist = *:<%=subnet%> 
<% end -%> 
Role assignment:
root@cloudcontrol1004:~# openstack role add --user deployment-prep-dns-manager --project deployement-prep designateadmin
root@cloudcontrol1004:~# openstack role add --user deployment-prep-dns-manager --project deployement-prep observer
root@cloudcontrol1003:~# openstack role assignment list --names --user deployment-prep-dns-manager
+----------------+-------------------------------------+-------+-------------------------+--------+-----------+
| Role | User | Group | Project | Domain | Inherited |
+----------------+-------------------------------------+-------+-------------------------+--------+-----------+
| observer | Deployment-prep-dns-manager@Default | | deployment-prep@Default | | False |
| designateadmin | Deployment-prep-dns-manager@Default | | deployment-prep@Default | | False |
+----------------+-------------------------------------+-------+-------------------------+--------+-----------+
root@cloudcontrol1003:~# openstack role assignment list --names --user traffic-cloud-dns-manager
+----------------+-----------------------------------+-------+-----------------+--------+-----------+
| Role | User | Group | Project | Domain | Inherited |
+----------------+-----------------------------------+-------+-----------------+--------+-----------+
| observer | Traffic-cloud-dns-manager@Default | | traffic@Default | | False |
| designateadmin | Traffic-cloud-dns-manager@Default | | traffic@Default | | False |
+----------------+-----------------------------------+-------+-----------------+--------+-----------+
== Troubleshooting ==
If your script gets an error when using the API like this:
keystoneauth1.exceptions.http.Unauthorized: The request you have made requires authentication. (HTTP 401) (Request-ID: req-c6f30f48-c91b-4681-a263-40df8df101df)
Or in the server, you see logs like these:
(keystone.middleware.auth): 2019-08-07 08:57:55,636 WARNING RBAC: Invalid token
(keystone.common.wsgi): 2019-08-07 08:57:55,639 WARNING The request you have made requires authentication.
(wmfkeystoneauth.password_whitelist): 2019-08-07 09:00:02,466 WARNING Password auth not allowed for traffic-cloud-dns-manager from 172.16.7.184
(keystone.common.wsgi): 2019-08-07 09:00:02,467 WARNING Authorization failed. The request you hav
This means that you need to add the user to the password_safelist setting in keystone.conf.
== See also ==
* The same applies to codfw1dev
* phabricator T229786: Create a service account to manage traffic.wmflabs.org. from acme-chief
* phabricator T194998: Create custom deployment-prep role that allows editing of Designate records only