diff --git a/_posts/en/2017-12-04-deploy-a-replicated-mongodb-on-aws-with-terraform-and-ansible.md b/_posts/en/2017-12-04-deploy-a-replicated-mongodb-on-aws-with-terraform-and-ansible.md new file mode 100644 index 000000000..55ced422b --- /dev/null +++ b/_posts/en/2017-12-04-deploy-a-replicated-mongodb-on-aws-with-terraform-and-ansible.md @@ -0,0 +1,399 @@ +--- +layout: post +title: Deploy a replicated MongoDB on AWS with Terraform and Ansible +lang: en +authors: + - vcomposieux +permalink: /deploy-a-replicated-mongodb-on-aws-with-terraform-and-ansible/ +categories: + - mongodb + - aws + - terraform + - ansible +tags: + - mongodb + - aws + - ansible + - terraform +cover: /assets/2017-09-03-migrer-une-application-react-client-side-en-server-side-avec-nextjs/cover.jpg +--- + +I recently had the opportunity to deploy a MongoDB server on Amazon Web Services (AWS). In order to limit the problems of crash and data loss, it is also replicated with two other servers, ideally in a different geographical area to ensure high availability. + +To automate the creation of EC2 machines, I used [Terraform](https://www.terraform.io/) (and its `aws` provider) as well as Ansible](https://www.ansible.com/) for provisioning and this article describes the technical logic that we set up to achieve this. + +# Context + +So we have a MongoDB cluster composed of three EC2 instances (say, `t2. large` type). + +Among these instances, MongoDB will elect a master server, called `primary` in the MongoDB language as well as slave servers, called `secondary`. + +In order for these three servers to share the same data, we will need to create what MongoDB calls a [replica set](https://docs.mongodb.com/manual/tutorial/deploy-replica-set/), a data set. + +What is important to note is that only the `primary` server will be able to read or write data. The `secondary` servers are there to take over in case the `primary` server is unavailable. This is possible thanks to an election that is launched automatically by MongoDB to elect a new `primary` server. + +This is the target infrastructure we are looking for for this replication: + +![MongoDB Replication](/assets/2017-11-01-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible/replication.svg) + + +As you can see on this diagram, only the primary node is used for read/write, the other two replicas are there to synchronize the updated data of the primary server in real time as well as for the purpose of eventually becoming primary in turn, in case the current primary server would become unavailable. + +The definition of a server (primary or secondary) is done through a majority election, which takes place between the servers. Thus, you will necessarily need to have at least three servers so that a majority can be constituted. + +It is therefore impossible to define this replication model with only two servers in your cluster. + +# Terraform: server creation + +So let's move on to the creation of machines on AWS: we have made the choice of [Terraform](https://www.terraform.io){"target":"_blank"} for this part, a resource automation tool. + +Terraform is therefore a tool for industrializing infrastructure tasks such as, in our case, the creation of EC2 machines on our AWS account. + +In order to create a MongoDB server (let's take the case of a first server), we use the following terraform code: + +``` +# EC2 Instance: MongoDB 1 +resource "aws_instance" "mongodb_one" { + availability_zone = "${var.AWS_REGION}a" + + tags { + Name = "${var.ENVIRONMENT}-mongodb-one" + } + + ami = "" + + instance_type = "t2.large" + + root_block_device { + volume_type = "gp2" + volume_size = "100" + } + + security_groups = [ + "${aws_security_group.mongodb.name}" + ] + + associate_public_ip_address = true + + key_name = "id_rsa" +} +``` + +In this script, we therefore specify a new resource of the type `aws_instance` and name it `mongodb-one`. + +This instance will be in the area `a` of our AWS region, defined as an environment variable. + +We must also specify the AMI image (Amazon Image) that will be used on this instance. To do this, I invite you to select an AMI identifier from those available on Amazon, using this command via the AWS CLI for example: + +```json +$ aws ec2 describe-images --filters "Name=root-device-type,Values=ebs" "Name=name,Values=ubuntu*hardy*" + +[ + { + "Architecture": "x86_64", + "CreationDate": "2011-10-07T09:09:03.000Z", + "ImageId": "ami-ffecde8b", + "ImageLocation": "063491364108/ubuntu-8.04-hardy-server-amd64-20111006", + "ImageType": "machine", + "Public": true, + "KernelId": "aki-4cf5c738", + "OwnerId": "063491364108", + "RamdiskId": "ari-2ef5c75a", + "State": "available", + "BlockDeviceMappings": [ + { + "DeviceName": "/dev/sda1", + "Ebs": { + "Encrypted": false, + "DeleteOnTermination": true, + "SnapshotId": "snap-eb7aa883", + "VolumeSize": 8, + "VolumeType": "standard" + } + }, + { + "DeviceName": "/dev/sdb", + "VirtualName": "ephemeral0" + } + ], + "Description": "Ubuntu 8.04 Hardy server amd64 20111006", + "Hypervisor": "xen", + "Name": "ubuntu-8.04-hardy-server-amd64-20111006", + "RootDeviceName": "/dev/sda1", + "RootDeviceType": "ebs", + "VirtualizationType": "paravirtual" + } + ... +] +``` + +You will have access to Ubuntu Hardy images supporting Amazon EBS (Elastic Block Storage) volumes. + +The field you will be interested in is `ImageId`, which you must copy into your Terraform code. + +We then specify the type of instance as well as the type of disk and sizing we want to use for our server. + +Next, you will also notice that we specify a `security_groups' entry for our instance that is dynamic and actually points to another resource we have to declare. + +So let's declare our security group for this MongoDB server: + +``` +# MongoDB security group +resource "aws_security_group" "mongodb" { + name = "mongodb-${var.ENVIRONMENT}" + description = "Security group for mongodb-${var.ENVIRONMENT}" + + tags { + Name = "mongodb-${var.ENVIRONMENT}" + } +} + +resource "aws_security_group_rule" "mongodb_allow_all" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_ssh" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_mongodb" { + type = "ingress" + from_port = 27017 + to_port = 27017 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_mongodb_replication" { + type = "ingress" + from_port = 27019 + to_port = 27019 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} +``` + +Here, a bunch of rules are specified in our security group. + +Here we need to allow the input ports `22` (SSH), `27017` (default port of MongoDB) and `27019` which is used by MongoDB to manage communication between servers. + +You will notice that we allow here all the provenances in the `cidr_blocks` entry, it is obviously necessary in fact to restrict these accesses as much as possible. + +We have now finished with the Terraform part: we are able to create a MongoDB (EC2) server on AWS but we still have to provision the server. + +# Ansible: provisioning + +To provision the MongoDB server, we use an Ansible playbook. Here is the definition of the playbook: + +```yaml +- hosts: db-mongodb + become: yes + roles: + - project.provision.mongodb +``` + +The `db-mongodb` host corresponds to both the primary and secondary servers. + +We distinguish these servers because we need to define a primary server first when we provision the cluster. + +``` +# Primary server +[db-mongodb-master] + ansible_user=root + +# Secondary servers +[db-mongodb-slave-1] + ansible_user=root + +[db-mongodb-slave-2] + ansible_user=root + +# MongoDB Groups +[db-mongodb-slave:children] +db-mongodb-slave-1 +db-mongodb-slave-2 + +[db-mongodb:children] +db-mongodb-master +db-mongodb-slave +``` + +For the `db-mongodb` host we will therefore play a `project. provision. mongodb` role that we will need to perform the following actions: + +* Installation and creation of a MongoDB system service +* Preparation of the MongoDB configuration file +* Activation of replication with other hosts +* Create user accounts +* Starting the MongoDB instance + +So let's start with the installation and activation of MongoDB: + +```yaml +- name: Install mongodb + apt: + name: mongodb-org + state: present + allow_unauthenticated: yes + +- name: Create systemd service file + template: + src: mongod.service + dest: /etc/systemd/system/mongodb.service + +- name: Enable Mongod service + command: systemctl enable mongodb.service + become: yes + when: env == 'dev' +``` + +Nothing very special so far. Note that the `mongod. service` file is directly available in our Ansible code and can be variabilized on certain values. + +This is also the case for the MongoDB configuration, which we also import to the server: + +```yaml +- name: Copy MongoDB configuration file + template: + src: mongod.conf + dest: /etc/mongod.conf +``` + +In order to enable replication, note that we need to specify in this configuration file, a set replica name (here, `rs0`): + +```yaml +replication: + replSetName: "rs0" +``` + +This replication cannot work only if the servers can communicate with each other. + +It is also important to secure these exchanges, which is why we will also create a key to authenticate the servers discussing between them: + +{% raw %} +```yaml +- name: Prepare authorization key file + local_action: shell openssl rand -base64 756 > {{ playbook_dir }}/passwords/{{ env }}/mongodb-key + when: database_replica_type == "master" + +- name: Create mongodb home directory + file: + state: directory + path: /home/mongodb + owner: mongodb + group: mongodb + mode: 0755 + +- name: Copies key to both master and slaves + copy: + src: "{{ playbook_dir + '/passwords/' + env + '/mongodb-key'}}" + dest: /home/mongodb/mongodb-key + owner: mongodb + group: mongodb + mode: 0400 + when: database_replica_type != false + +- name: Add key to mongodb configuration + lineinfile: + dest: /etc/mongod.conf + state: present + regexp: '# keyFile:' + line: ' keyFile: /home/mongodb/mongodb-key' + backrefs: yes + when: database_replica_type != false +``` +{% endraw %} + +We create here the necessary key with `openssl`, copy it on the servers and specify it in the configuration file (a restart of MongoDB will be necessary then to take this key into account). + +Finally, let's boot or reboot our MongoDB servers using the system service previously created: + +```yaml +- name: Restart mongodb + command: systemctl restart mongodb.service +``` + +When you then connect to your different MongoDB servers, you will have the `PRIMARY` or `SECONDARY` element in the console, as in the example below, which allows you to know where you are: + +``` +root@mongodb:~# mongo --host localhost -u user -p admin +MongoDB shell version: 3.2.17 +connecting to: localhost:27017/admin +rs0:PRIMARY> +``` + +You can also check the configuration of your replication via the `rs. conf ()` command in the different MongoDB servers: + +``` +rs0:PRIMARY> rs.conf() +{ + "_id" : "rs0", + "version" : 3, + "protocolVersion" : NumberLong(1), + "members" : [ + { + "_id" : 0, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + }, + { + "_id" : 1, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + }, + { + "_id" : 2, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + } + ], + ... +``` + +Thus, no more doubt about your configuration. You also have the option of giving weight to certain servers that will allow you to influence the elections of a new primary server in case of a failure on your cluster via the `priority` property. + +# Conclusion + +Deploying a MongoDB cluster with an active replication on a specified infrastructure via Terraform code and provisioned with Ansible is really very simple. Indeed, MongoDB makes things much easier for us because it only takes a few lines of configuration to activate replication. + +The whole logic of primary server election and re-definition is managed by MongoDB. + +To go further with MongoDB replication, I invite you to browse the official MongoDB documentation which explains very well, with diagrams, operation and the various configuration parameters available to configure your replicas:[https://docs.mongodb.com/v3.0/core/replication-introduction/#replication-introduction](https://docs.mongodb.com/v3.0/core/replication-introduction/#replication-introduction){"target":"_blank"}. \ No newline at end of file diff --git a/_posts/fr/2017-12-04-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible.md b/_posts/fr/2017-12-04-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible.md new file mode 100644 index 000000000..6c8570ef0 --- /dev/null +++ b/_posts/fr/2017-12-04-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible.md @@ -0,0 +1,399 @@ +--- +layout: post +title: Déployer un serveur MongoDB répliqué sur AWS avec Terraform et Ansible +lang: fr +authors: + - vcomposieux +permalink: /fr/deployer-un-serveur-mongodb-replique-sur-aws-avec-terraform-et-ansible/ +categories: + - mongodb + - aws + - terraform + - ansible +tags: + - mongodb + - aws + - ansible + - terraform +cover: /assets/2017-09-03-migrer-une-application-react-client-side-en-server-side-avec-nextjs/cover.jpg +--- + +J'ai récemment eu l'occasion de déployer un serveur MongoDB sur Amazon Web Services (AWS). Afin de limiter les problèmes de crash et de perte de données, celui-ci est également répliqué avec deux autres serveurs, idéalement dans une zone géographique différente pour assurer de la haute disponibilité. + +Pour l'automatisation de la création des machines EC2, j'ai utilisé [Terraform](https://www.terraform.io/) (et son provider `aws`) ainsi que [Ansible](https://www.ansible.com/) pour le provisionnement et cet article décrit la logique technique que nous avons mis en place pour y arriver. + +# Contexte + +Nous avons donc un cluster MongoDB composé de trois instances EC2 (disons de type `t2.large`). + +Parmi ces instances, MongoDB va élire un serveur master, appelé `primaire` dans le langage MongoDB ainsi que des serveurs slaves, appelés `secondaires`. + +Afin que ces trois serveurs se partagent les mêmes données, nous allons devoir créer ce que MongoDB appelle un [replica set](https://docs.mongodb.com/manual/tutorial/deploy-replica-set/), un ensemble de données. + +Ce qu'il est important de noter est que seul le serveur `primaire` pourra lire ou écrire des données. Les serveurs `secondaires` sont là pour prendre le relai au cas ou le serveur `primaire` serait amené à être indisponible. Ceci est possible grâce à une élection qui est lancée automatiquement par MongoDB pour élire un nouveau serveur `primaire`. + +Voici donc l'infrastructure cible que nous cherchons à obtenir pour cette réplication : + +![MongoDB Replication](/assets/2017-11-01-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible/replication.svg) + + +Comme vous pouvez le voir sur ce schéma, seul le noeud primaire est utilisé pour la lecture/écriture, les deux autres réplicas sont là pour la synchronisation des données à jour du serveur primaire en temps réel ainsi que dans le but d'éventuellement devenir primaire à leur tour, dans le cas ou le serveur primaire actuel viendrait à devenir indisponible. + +La définition d'un serveur (primaire ou secondaire) se fait via le biais d'une élection à la majorité, qui a lieue entre les serveurs. Ainsi, vous aurez forcément besoin d'avoir au minimum trois serveurs afin qu'une majorité puisse être constituée. + +Impossible donc de définir ce modèle de réplication avec seulement deux serveurs dans votre cluster. + +# Terraform : création des serveurs + +Passons donc à la création des machines sur AWS : nous avons fait le choix de ![Terraform](https://www.terraform.io){"target":"_blank"} pour cette partie, un outil d'automatisation de ressources. + +Terraform est donc un outil permettant d'industrialiser des tâches d'infrastructure tel que, dans notre cas, la création de machines EC2 sur notre compte AWS. + +Afin de créer un serveur MongoDB (prenons ici le cas d'un premier serveur), nous utilisons le code terraform suivant : + +``` +# EC2 Instance: MongoDB 1 +resource "aws_instance" "mongodb_one" { + availability_zone = "${var.AWS_REGION}a" + + tags { + Name = "${var.ENVIRONMENT}-mongodb-one" + } + + ami = "" + + instance_type = "t2.large" + + root_block_device { + volume_type = "gp2" + volume_size = "100" + } + + security_groups = [ + "${aws_security_group.mongodb.name}" + ] + + associate_public_ip_address = true + + key_name = "id_rsa" +} +``` + +Dans ce script, nous spécifions donc une nouvelle ressource de type `aws_instance` et la nommons `mongodb-one`. + +Cette instance sera dans la zone `a` de notre région AWS, définie en variable d'environnement. + +Nous devons également spécifier l'image AMI (Amazon Image) qui sera utilisée sur cette instance. Pour ce faire, je vous invite à sélectionner un identifiant d'AMI parmi celles disponibles sur Amazon, en utilisant cette commande via le CLI AWS par exemple : + +```json +$ aws ec2 describe-images --filters "Name=root-device-type,Values=ebs" "Name=name,Values=ubuntu*hardy*" + +[ + { + "Architecture": "x86_64", + "CreationDate": "2011-10-07T09:09:03.000Z", + "ImageId": "ami-ffecde8b", + "ImageLocation": "063491364108/ubuntu-8.04-hardy-server-amd64-20111006", + "ImageType": "machine", + "Public": true, + "KernelId": "aki-4cf5c738", + "OwnerId": "063491364108", + "RamdiskId": "ari-2ef5c75a", + "State": "available", + "BlockDeviceMappings": [ + { + "DeviceName": "/dev/sda1", + "Ebs": { + "Encrypted": false, + "DeleteOnTermination": true, + "SnapshotId": "snap-eb7aa883", + "VolumeSize": 8, + "VolumeType": "standard" + } + }, + { + "DeviceName": "/dev/sdb", + "VirtualName": "ephemeral0" + } + ], + "Description": "Ubuntu 8.04 Hardy server amd64 20111006", + "Hypervisor": "xen", + "Name": "ubuntu-8.04-hardy-server-amd64-20111006", + "RootDeviceName": "/dev/sda1", + "RootDeviceType": "ebs", + "VirtualizationType": "paravirtual" + } + ... +] +``` + +Vous aurez ainsi accès aux images Ubuntu Hardy supportant les volumes EBS (Elastic Block Storage) Amazon. + +Le champ qui vous intéressera est bien sûr `ImageId`, que vous devez copier dans votre code Terraform. + +Nous spécifions ensuite le type d'instance ainsi que le type de disque et le sizing que nous souhaitons utiliser pour notre serveur. + +Ensuite, vous noterez également que nous spécifions une entrée `security_groups` (groupe de sécurité) pour notre instance qui est dynamique et qui pointe en faite sur une autre ressource que nous avons à déclarer. + +Ainsi, déclarons notre groupe de sécurité pour ce serveur MongoDB : + +``` +# MongoDB security group +resource "aws_security_group" "mongodb" { + name = "mongodb-${var.ENVIRONMENT}" + description = "Security group for mongodb-${var.ENVIRONMENT}" + + tags { + Name = "mongodb-${var.ENVIRONMENT}" + } +} + +resource "aws_security_group_rule" "mongodb_allow_all" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_ssh" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_mongodb" { + type = "ingress" + from_port = 27017 + to_port = 27017 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} + +resource "aws_security_group_rule" "mongodb_mongodb_replication" { + type = "ingress" + from_port = 27019 + to_port = 27019 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = "${aws_security_group.mongodb.id}" +} +``` + +Ici, un tas de règles sont spécifiées dans notre groupe de sécurité. + +Nous avons en effet besoin ici d'autoriser en entrée les ports `22` (SSH), `27017` (port par défaut de MongoDB) ainsi que `27019` qui est utilisé par MongoDB pour gérer les communications entre les serveurs. + +Vous noterez que l'on autorise ici toutes les provenances dans l'entrée `cidr_blocks`, il faut bien évidemment dans les faits restreindre au maximum ces accès. + +Nous en avons terminé avec la partie Terraform : nous sommes capables de créer un serveur MongoDB (EC2) sur AWS mais il nous reste à provisionner le serveur. + +# Ansible : provisioning + +Pour provisionner le serveur MongoDB, nous utilisons donc un playbook Ansible. Voici la définition du playbook : + +```yaml +- hosts: db-mongodb + become: yes + roles: + - project.provision.mongodb +``` + +Le host `db-mongodb` correspond à la fois au serveur primaire ainsi qu'aux serveurs secondaires. + +Nous distinguons ces serveurs car nous devons définir un premier serveur primaire lorsque nous allons provisionner le cluster. + +``` +# Primary server +[db-mongodb-master] + ansible_user=root + +# Secondary servers +[db-mongodb-slave-1] + ansible_user=root + +[db-mongodb-slave-2] + ansible_user=root + +# MongoDB Groups +[db-mongodb-slave:children] +db-mongodb-slave-1 +db-mongodb-slave-2 + +[db-mongodb:children] +db-mongodb-master +db-mongodb-slave +``` + +Pour le host `db-mongodb` nous allons donc jouer un rôle `project.provision.mongodb` dont nous allons avoir le besoin d'effectuer les actions suivantes : + +* Installation et création d'un service système MongoDB +* Préparation du fichier de configuration MongoDB +* Activation de la réplication avec les autres hosts +* Création des comptes utilisateur +* Démarrage de l'instance MongoDB + +Commençons donc par l'installation et l'activation de MongoDB : + +```yaml +- name: Install mongodb + apt: + name: mongodb-org + state: present + allow_unauthenticated: yes + +- name: Create systemd service file + template: + src: mongod.service + dest: /etc/systemd/system/mongodb.service + +- name: Enable Mongod service + command: systemctl enable mongodb.service + become: yes + when: env == 'dev' +``` + +Rien de très spécial jusque-là. Notez que le fichier `mongod.service` est directement disponible dans notre code Ansible et peut être variabilisé sur certaines valeurs. + +C'est également le cas pour la configuration MongoDB que nous importons également sur le serveur : + +```yaml +- name: Copy MongoDB configuration file + template: + src: mongod.conf + dest: /etc/mongod.conf +``` + +Afin d'activer la replication, notez que nous avons besoin de spécifier dans ce fichier de configuration, un nom de replica set (ici, `rs0`) : + +```yaml +replication: + replSetName: "rs0" +``` + +Cette réplication ne peut fonctionner uniquement dans le cas ou les serveurs peuvent communiquer entre eux. + +Il est également important de sécuriser ces échanges, c'est pourquoi nous allons également créer une clé qui aura pour but d'authentifier les serveurs discutant entre eux : + +{% raw %} +```yaml +- name: Prepare authorization key file + local_action: shell openssl rand -base64 756 > {{ playbook_dir }}/passwords/{{ env }}/mongodb-key + when: database_replica_type == "master" + +- name: Create mongodb home directory + file: + state: directory + path: /home/mongodb + owner: mongodb + group: mongodb + mode: 0755 + +- name: Copies key to both master and slaves + copy: + src: "{{ playbook_dir + '/passwords/' + env + '/mongodb-key'}}" + dest: /home/mongodb/mongodb-key + owner: mongodb + group: mongodb + mode: 0400 + when: database_replica_type != false + +- name: Add key to mongodb configuration + lineinfile: + dest: /etc/mongod.conf + state: present + regexp: '# keyFile:' + line: ' keyFile: /home/mongodb/mongodb-key' + backrefs: yes + when: database_replica_type != false +``` +{% endraw %} + +Nous créons donc ici la clé nécessaire avec `openssl`, la copions sur les serveurs et la spécifions dans le fichier de configuration (un redémarrage de MongoDB sera nécessaire ensuite afin de prendre en compte cette clé). + +Finalement, démarrons ou redémarrons nos serveurs MongoDB à l'aide du service système précédemment créé : + +```yaml +- name: Restart mongodb + command: systemctl restart mongodb.service +``` + +Lorsque vous connecterez ensuite à vos différents serveurs MongoDB, vous aurez donc l'élément `PRIMARY` ou `SECONDARY` dans la console, comme dans l'exemple ci-dessous, ce qui vous permet de savoir ou vous vous situez : + +``` +root@mongodb:~# mongo --host localhost -u user -p admin +MongoDB shell version: 3.2.17 +connecting to: localhost:27017/admin +rs0:PRIMARY> +``` + +Vous pouvez également vérifier la configuration de votre réplication via la commande `rs.conf()` dans les différents serveurs MongoDB : + +``` +rs0:PRIMARY> rs.conf() +{ + "_id" : "rs0", + "version" : 3, + "protocolVersion" : NumberLong(1), + "members" : [ + { + "_id" : 0, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + }, + { + "_id" : 1, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + }, + { + "_id" : 2, + "host" : ":27017", + "arbiterOnly" : false, + "buildIndexes" : true, + "hidden" : false, + "priority" : 1, + "tags" : { + + }, + "slaveDelay" : NumberLong(0), + "votes" : 1 + } + ], + ... +``` + +Ainsi, plus de doute sur votre configuration. Vous avez également la possibilité de donner du poids à certains serveur qui permettra d'influencer les élections d'un nouveau serveur primaire en cas de panne sur votre cluster via la propriété `priority`. + +# Conclusion + +Déployer un cluster MongoDB avec un réplication active sur une infrastructure spécifiée via du code Terraform et provisionnée avec Ansible est vraiment très simple. En effet, MongoDB nous facilite beaucoup les choses car il ne suffit que quelques lignes de configuration pour activer la réplication. + +Toute la logique d'élection et de re-définition de serveur primaire est gérée par MongoDB. + +Pour aller plus loin au niveau de la réplication MongoDB, je vous invite à parcourir la documentation officielle de MongoDB qui explique très bien, avec des schémas, le fonctionnement et les différents paramètres de configuration disponibles pour configurer au mieux vos réplicas : [https://docs.mongodb.com/v3.0/core/replication-introduction/#replication-introduction](https://docs.mongodb.com/v3.0/core/replication-introduction/#replication-introduction){"target":"_blank"} \ No newline at end of file diff --git a/assets/2017-11-01-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible/replication.svg b/assets/2017-11-01-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible/replication.svg new file mode 100644 index 000000000..06d9984ca --- /dev/null +++ b/assets/2017-11-01-deployer-un-mongodb-replique-sur-aws-avec-terraform-et-ansible/replication.svg @@ -0,0 +1 @@ + \ No newline at end of file