On the other hand, if you're using kubespray to provision your servers, kubespray supports multi-node etcd natively. What you need to do is add multiple nodes in the etcd section in the configuration file (inventory.cfg):
# cat inventory/inventory.cfg
my-master-1 ansible_ssh_host=<master_ip>
my-node-1 ansible_ssh_host=<node_ip>
my-etcd-1 ansible_ssh_host=<etcd1_ip>
my-etcd-2 ansible_ssh_host=<etcd2_ip>
my-etcd-3 ansible_ssh_host=<etcd3_ip>
[kube-master]
my-master-1
[etcd]
my-etcd-1
my-etcd-2
my-etcd-3
[kube-node]
my-master-1
my-node-1
Then you are good to provision a cluster with three-node etcd:
// provision a cluster
$ ansible-playbook -b -i inventory/inventory.cfg cluster.yml
After the ansible playbook is launched, it will configure the role, create the user, check if all certs have already been generated in the first master, and generate and distribute the certs. At the end of the deployment, ansible will check if every component is in a healthy state.