Thursday, April 27, 2017

What is better for AWS entities management: Ansible or Terraform ?



Ansible is a configuration management tool which is able to provision any AWS entities and then do any deploy / configuration actions on them.
To manage AWS entities Ansible uses boto. To configure instances, Ansible uses SSH and various official modules written at Python (Ansible copies module to the host via SSH, and then executes it there via SSH)

Example Ansible modules are:
1. https://docs.ansible.com/ansible/docker_container_module.html - module for spinning up Docker containers.
Using it, it takes 1-2 days to build a flexible Ansible-based tool acting as a docker-compose but for many remote hosts (and not one local host as docker-compose does).
2. http://docs.ansible.com/ansible/ec2_module.html - module for spinning up EC2 instances.
Using it, it takes 1-2 days to build a flexible automation script able to spin up any number of hosts in existing VPC with related volumes, security groups, Elastic IPs, and so on.
3. http://docs.ansible.com/ansible/ec2_vpc_module.html, https://docs.ansible.com/ansible/ec2_vpc_peer_module.html - modules for spinning up Amazon VPCs and peering them for cross-VPC connectivity

All these Ansible modules are included out-the-box.

Most Ansible modules allow declarative setup and support the "infrastructure as code" pattern, but it is better to call Ansible a procedural rather than declarative tool.
Each Ansible task is a procedure, is aware about existing host state (via Ansible "facts aggregation"). Then it is a programmer responsibility to check this state in the code and do only those high-level steps that are needed.

Example: in you need Ansible script which adds swap to hosts, you write several declarative steps, namely: 'ensure swapfile', 'ensure swapfile is formatted', and 'ensure swap file is added to fstab'.
Then you put the check in code which checks the 'ansible_swap_total' fact (which is gathered from host by Ansible) and decides if these declarative steps needs to be (re)applied.
Then, in case if host already have swap configured, all steps would be skipped. During our call, I am going to show this example in details via screenshare.

Using Ansible, it is possible to automate any action on the host - configuration management, complicated deployments, spinning up and linking docker containers.
All Ansible modules are consistent and reliable, but for better reliability with Ansible it is better to:
- Dockerize Ansible, so the same version of Ansible and it's deps is used between runs at different environments
- Avoid any manual actions on hosts thus reducing the "configuration drift" effects
- In case of complicated changes, always prefer to re-create instances instead of re-configuring them

Terraform positions itself as an orchestration tool, but this name can be misleading. Terraform is actually a tool for spinning resources (instances, networks, load balancers, autoscaling groups, etc.) which supports various cloud providers, including AWS.
Terraform itself doesn't do anything about provisioning instances inside after their creation, it can only call 3-rd party 'provisioners' (shell, Ansible, Chef, Puppet, etc.) as a post-instance-creation hook.
Terraform is not as flexible as Anisble in resources creation. With Terraform, you usually can't write the code in between of any resource creation step, e.g. Terraform does not even support if statements.
Kill features of Terraform are:
- it is written to be fully declarative
- it is better aware of the system state. If you run 2 subnets and provision 20 instances on each, and then you will want to scale up to 30 instances per subnet, you just tell Terraform the new count and it adds +10 instances where needed

No comments:

Post a Comment