Terraform/fr: Difference between revisions
(Created page with "[https://www.terraform.io/ Terraform] est un outil permettant de définir et d'approvisionner l'infrastructure de centres de données, y compris des machines virtuelles. Terraform est de plus en plus utilisé au sein de Compute Canada. Son modèle d'infrastructure-en-code permet de maintenir les ressources OpenStack comme une collection de définitions qui peuvent être facilement mises à jour à l'aide de nos éditeurs de texte favoris, partagées entre les membres d...") |
(Created page with "Vous obtiendrez une liste des images disponibles pour votre projet. Cliquez sur celle que vous voulez utiliser. (2)") |
||
(70 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
<languages /> | <languages /> | ||
[https://www.terraform.io/ Terraform] est un outil | [https://www.terraform.io/ Terraform] est un outil qui permet de définir et d'approvisionner l'infrastructure de centres de données, y compris des machines virtuelles. Terraform est de plus en plus utilisé au sein de l'Alliance. Son modèle d'infrastructure-en-code permet de maintenir les ressources OpenStack comme une collection de définitions qui peuvent être facilement mises à jour à l'aide des éditeurs de texte, partagées entre les membres d'un groupe et stockées dans un système de contrôle de version. | ||
Cette page est écrite comme un tutoriel dans lequel nous présentons Terraform et démontrons son utilisation sur nos nuages OpenStack. Nous configurons notre espace de travail local pour Terraform et créons une machine virtuelle (VM pour <i>virtual machine</i>) avec une IP flottante et un volume attaché. | |||
== Préparation == | == Préparation == | ||
Avant de commencer avec Terraform, vous avez besoin | |||
* | * d'un accès à un projet OpenStack avec des ressources disponibles, | ||
* | * d'installer le binaire <code>terraform</code>, | ||
* | * d'effectuer quelques configurations sur votre poste de travail ou ordinateur portable. | ||
=== Accéder à OpenStack === | === Accéder à OpenStack === | ||
Pour accéder au nuage, voir [[Cloud/fr#Obtenir_un_projet_dans_l'environnement_infonuagique|Obtenir un projet dans l'environnement infonuagique]] sur le wiki de l'Alliance. Si vous n'avez jamais utilisé OpenStack auparavant, vous devriez d'abord vous familiariser avec ce système en créant une machine virtuelle, en attachant un volume, en associant une IP flottante et en vous assurant que vous pouvez vous connecter à la machine virtuelle par la suite. Ce tutoriel suppose également que vous avez déjà créé une paire de clés SSH et que la clé publique a été importée dans OpenStack. | |||
Si vous ne savez pas encore comment faire cela, le [[Cloud_Quick_Start/fr|Guide de démarrage]] est une bonne introduction. La création de ces ressources à l'aide de l'interface web d'OpenStack vous permettra de comprendre le fonctionnement et l'utilité de Terraform. | |||
=== | === Installer Terraform === | ||
Consultez la [https://www.terraform.io/downloads.html | Consultez la [https://www.terraform.io/downloads.html page de téléchargement] de Terraform pour obtenir la dernière version du binaire. Nous utilisons ici Terraform 0.12. | ||
=== | === S'identifier pour OpenStack === | ||
There are two ways to provide your OpenStack credentials in a command-line environment: via environment variables or in a configuration file. We'll need to use one of these methods with Terraform, described in the [[#Defining_OpenStack_provider|next section]]. Regardless of your preferred method, the OpenStack web interface offers a simple way to download credentials: once logged in, click on | There are two ways to provide your OpenStack credentials in a command-line environment: via environment variables or in a configuration file. We'll need to use one of these methods with Terraform, described in the [[#Defining_OpenStack_provider|next section]]. Regardless of your preferred method, the OpenStack web interface offers a simple way to download credentials: once logged in, click on <i>API Access</i> in the navigation bar, and on that page is a drop-down menu entitled “Download OpenStack RC File”. From here you may download a <code>clouds.yaml</code> file or an RC file which can be sourced from your shell session. | ||
Le fichier RC contient une liste de commandes pour l'interpréteur qui servent à exporter les variables d'environnement dans votre session active. Il ne s'agit pas d'un script indépendant et il doit recevoir de l'information par | |||
<source lang="shell">$ source openrc.sh</source> | <source lang="shell">$ source openrc.sh</source> | ||
Vous devez alors entrer votre mot de passe OpenStack qui sera enregistré dans une variable d'environnement préfixée par <code>OS_</code>. D'autres variables d'environnement seront créées avec certains renseignements sur vous, votre projet et le nuage auquel vous voulez vous connecter, par exemple | |||
The other method is to create a configuration in <code>$HOME/.config/openstack/clouds.yaml</code>. If you don’t have such a file already, you can download `clouds.yaml` as described above and move it into place. We recommend changing the name given to the cloud in the downloaded file to something meaningful, especially if you use more than one OpenStack cloud. Then, to use the CLI tools described below, simply create an environment variable <code>$OS_CLOUD</code> with the name of the cloud you want to use. | The other method is to create a configuration in <code>$HOME/.config/openstack/clouds.yaml</code>. If you don’t have such a file already, you can download `clouds.yaml` as described above and move it into place. We recommend changing the name given to the cloud in the downloaded file to something meaningful, especially if you use more than one OpenStack cloud. Then, to use the CLI tools described below, simply create an environment variable <code>$OS_CLOUD</code> with the name of the cloud you want to use. | ||
Line 34: | Line 34: | ||
<source lang="shell">$ export OS_CLOUD=arbutus</source> | <source lang="shell">$ export OS_CLOUD=arbutus</source> | ||
Peu importe ce que vous choisissez, vous utiliserez ceci pour configurer Terraform. | |||
=== Session OpenStack === | === Session OpenStack === | ||
Line 40: | Line 40: | ||
It is helpful to have a terminal window open running the OpenStack CLI. This provides a handy reference for the specifications you will be building, as you will be looking up flavour and image IDs, and it is useful for verifying the actions performed by Terraform. Horizon can be used for looking up images, and for verifying in general that Terraform is having the intended effects, but it is not possible to directly lookup flavour IDs. | It is helpful to have a terminal window open running the OpenStack CLI. This provides a handy reference for the specifications you will be building, as you will be looking up flavour and image IDs, and it is useful for verifying the actions performed by Terraform. Horizon can be used for looking up images, and for verifying in general that Terraform is having the intended effects, but it is not possible to directly lookup flavour IDs. | ||
OpenStack CLI (aussi appelé <i>OSC</i>) est un client Python qui peut être installé avec Python Pip et qui [https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html ests disponibles pour plusieurs distribuitions et systèmes d'exploitation]. | |||
=== | === Espace de travail === | ||
Créez enfin un répertoire pour vos fichiers de configuration et d'état qui servira de point de départ. | |||
== Defining OpenStack provider == | == Defining OpenStack provider == | ||
First, describe the | First, describe the <i>provider</i>: this is where you tell Terraform to use OpenStack, and how. On initialization the most recent version of the OpenStack provider plugin will be installed in the working directory and on subsequent Terraform operations, the included credentials will be used to connect to the specified cloud. | ||
Your connection and credential information for OpenStack can be provided to Terraform in the specification, in the environment, or partially in the specification with the rest in the environment. | Your connection and credential information for OpenStack can be provided to Terraform in the specification, in the environment, or partially in the specification with the rest in the environment. | ||
Line 63: | Line 63: | ||
}</source> | }</source> | ||
For some OpenStack instances the above would specify the complete set of information necessary to connect to the instance and manage resources in the given project (“tenant”). However, Terraform supports | For some OpenStack instances, the above would specify the complete set of information necessary to connect to the instance and manage resources in the given project (“tenant”). However, Terraform supports <i>partial credentials</i> in which you could leave some values out of the Terraform configuration and supply them a different way. This would allow us, for example, to leave the password out of the configuration file, in which case it would need to be specified in the environment with <code>$OS_PASSWORD</code>. | ||
Alternatively, if you prefer to use <code>clouds.yaml</code>, specify <code>cloud</code> in the provider stanza: | Alternatively, if you prefer to use <code>clouds.yaml</code>, specify <code>cloud</code> in the provider stanza: | ||
Line 71: | Line 71: | ||
}</source> | }</source> | ||
Il n'est pas nécessaire d'entrer une définition pour <i>provider</i>. | |||
<source lang="terraform">provider "openstack" { | <source lang="terraform">provider "openstack" { | ||
Line 80: | Line 80: | ||
The [https://www.terraform.io/docs/providers/openstack/index.html configuration reference of the OpenStack Provider] describes the available options in detail. | The [https://www.terraform.io/docs/providers/openstack/index.html configuration reference of the OpenStack Provider] describes the available options in detail. | ||
=== | === Ce que vous devriez utiliser === | ||
It may be tempting to leave some of the details in the environment so that the Terraform configuration is more portable or reusable, but as we will see later, the Terraform configuration will and must contain details which are specific to each cloud, such as flavour and image UUIDs, network names, and tenants. | It may be tempting to leave some of the details in the environment so that the Terraform configuration is more portable or reusable, but as we will see later, the Terraform configuration will and must contain details which are specific to each cloud, such as flavour and image UUIDs, network names, and tenants. | ||
Line 120: | Line 120: | ||
This shows success in initializing Terraform and downloading the OpenStack provider plugin so the OpenStack stanzas will be handled correctly. This does not test out the credentials because this operation doesn’t actually try to connect to the defined provider. | This shows success in initializing Terraform and downloading the OpenStack provider plugin so the OpenStack stanzas will be handled correctly. This does not test out the credentials because this operation doesn’t actually try to connect to the defined provider. | ||
== | == Définir une VM == | ||
Définissions maintenant une VM de base. | |||
<blockquote> | <blockquote><b>Important</b>: It is good practice to <b>always</b> specify flavours and images using their IDs even when Terraform supports using the name. Although the name is more readable, the ID is what actually defines the state of the resource and the ID of a given image or flavour <b>will never change</b>. It is possible, however, for the <b>name</b> to change. If a flavour or image is retired, for example, and replaced with another of the same name, the next time you run Terraform, the updated ID will be detected and Terraform will determine that you want to <b>rebuild or resize the associated resource</b>. This is a destructive (and reconstructive) operation. | ||
</blockquote> | </blockquote> | ||
A minimal OpenStack VM may be defined as follows in Terraform: | A minimal OpenStack VM may be defined as follows in Terraform: | ||
Line 136: | Line 136: | ||
}</source> | }</source> | ||
Ceci crée une VM ayant le nom, l'image et le gabarit indiqués et associe la VM avec une paire de clés et le groupe de sécurité par défaut. | |||
<blockquote> | <blockquote><b>Note</b>: If you’re following along (please do!), use your own values for <code>image_id</code>, <code>flavor_id</code>, and <code>key_pair</code>, or this will probably fail! | ||
</blockquote> | </blockquote> | ||
The values for <code>image_id</code> and <code>flavor_id</code> are one reason I like to have a terminal session open running the OpenStack CLI, connected to the cloud I’m targeting with Terraform: I switch over to it and issue <code>flavor list</code> or <code>image list</code>. These list the names and IDs. | The values for <code>image_id</code> and <code>flavor_id</code> are one reason I like to have a terminal session open running the OpenStack CLI, connected to the cloud I’m targeting with Terraform: I switch over to it and issue <code>flavor list</code> or <code>image list</code>. These list the names and IDs. | ||
Line 144: | Line 144: | ||
If using Horizon (the OpenStack web interface), this is semi-possible–see the [[#Finding_image_and_flavour_UUIDs_in_Horizon|guide in the appendix]]. | If using Horizon (the OpenStack web interface), this is semi-possible–see the [[#Finding_image_and_flavour_UUIDs_in_Horizon|guide in the appendix]]. | ||
Note that no volumes are supplied. A compute instance | Note that no volumes are supplied. A compute instance on our clouds will already have an associated volume but a persistent instance will probably fail unless there is sufficient empty space in the image itself. It is [[Working_with_volumes#Booting_from_a_volume|recommended that a boot volume be created]] for VMs using persistent flavours. | ||
=== Trying it out === | === Trying it out === | ||
La commande <code>terraform plan</code> compile la définition de Terraform, tente de déterminer comment réconcilier l'état résultant avec l'état actuel du nuage et produit un plan des modifications qui s'appliqueraient. | |||
<source lang="shell">$ terraform plan | <source lang="shell">$ terraform plan | ||
Line 205: | Line 205: | ||
"terraform apply" is subsequently run.</source> | "terraform apply" is subsequently run.</source> | ||
Prenez connaissance du résultat. Même s'il contient beaucoup d'information, <i>il est nécessaire d'en connaître le contenu</i> avant d'accepter les modifications afin d'éviter les mauvaises surprises. | |||
<blockquote>If you get an error about incomplete credentials, you may have forgotten to define <code>OS_CLOUD</code> or source the RC file, or your <code>clouds.yaml</code> file may be missing.</blockquote> | <blockquote>If you get an error about incomplete credentials, you may have forgotten to define <code>OS_CLOUD</code> or source the RC file, or your <code>clouds.yaml</code> file may be missing.</blockquote> | ||
Line 211: | Line 211: | ||
These values are to resources as they’d be defined in OpenStack. Anything marked <code>known after apply</code> will be determined from the state of newly created resources queried from OpenStack. Other values are set according to what we’ve defined or determined by the Terraform and the OpenStack plugin as either calculated or default values. | These values are to resources as they’d be defined in OpenStack. Anything marked <code>known after apply</code> will be determined from the state of newly created resources queried from OpenStack. Other values are set according to what we’ve defined or determined by the Terraform and the OpenStack plugin as either calculated or default values. | ||
Si vous n'avez pas le temps et que ce n'est pas grave de détruire accidentellement des ressources ou de les reconstruire, <b>prenez au moins le temps</b> de vérifier la dernière ligne du plan. | |||
<source lang="shell">Plan: 1 to add, 0 to change, 0 to destroy.</source> | <source lang="shell">Plan: 1 to add, 0 to change, 0 to destroy.</source> | ||
In this case we know we’re adding a resource so this looks right. If the other values were non-zero then we’d better have another look at our configuration, state and what’s actually defined in OpenStack and make whatever corrections are necessary. | In this case, we know we’re adding a resource so this looks right. If the other values were non-zero then we’d better have another look at our configuration, state and what’s actually defined in OpenStack and make whatever corrections are necessary. | ||
=== | === Que se passe-t-il avec les ressources OpenStack déjà existantes? === | ||
Si des VM sont déjà définies dans votre projet OpenStack, vous vous demandez peut-être si Terraform affectera ces ressources. | |||
Eh bien non. Terraform ne connait pas les ressources qui sont déjà définies pour le projet et n'essaie pas d'en déterminer l'état. Les actions de Terraform se basent sur la configuration fournie et sur l'état précédemment déterminé dans la configuration. Les ressources existantes ne sont pas représentées dans Terraform et lui sont invisibles. | |||
It is possible to import previously defined OpenStack resources into Terraform but [https://dleske.gitlab.io/posts/terraform-import-manually/ it is not a trivial amount of work] and outside the scope of this tutorial. The important thing here is that any existing resources in your OpenStack project are safe from inadvertent mangling from Terraform—but just to be on the safe side, why don’t you make sure you read the output plans carefully? :) | It is possible to import previously defined OpenStack resources into Terraform but [https://dleske.gitlab.io/posts/terraform-import-manually/ it is not a trivial amount of work] and outside the scope of this tutorial. The important thing here is that any existing resources in your OpenStack project are safe from inadvertent mangling from Terraform—but just to be on the safe side, why don’t you make sure you read the output plans carefully? :) | ||
=== | === Appliquer la configuration === | ||
Utilisez <code>terraform apply</code> pour effectuer le changement décrit dans le plan. | |||
<source lang="shell">$ terraform apply | <source lang="shell">$ terraform apply | ||
Line 259: | Line 259: | ||
4: resource "openstack_compute_instance_v2" "myvm" {</source> | 4: resource "openstack_compute_instance_v2" "myvm" {</source> | ||
Dans notre exemple, ceci échoue. Il y a au moins deux réseaux qui sont définis pour un projet OpenStack : un privé et un public. Terraform a besoin de savoir lequel utililser. | |||
== Ajouter un réseau == | == Ajouter un réseau == | ||
The name of the private network differs from project to project and the naming convention can differ from cloud to cloud | The name of the private network differs from project to project and the naming convention can differ from cloud to cloud, but typically they are on a 192.168.X.Y network, and can be found in the CLI using `network list` or on Horizon under <i>Network -> Networks</i>. If your project's private network is <code>my-tenant-net</code>, you will add a <code>network</code> resource sub-block to your VM definition similar to the following: | ||
<source lang="terraform">resource "openstack_compute_instance_v2" "myvm" { | <source lang="terraform">resource "openstack_compute_instance_v2" "myvm" { | ||
Line 277: | Line 277: | ||
}</source> | }</source> | ||
Essayez de nouveau. | |||
<source lang="shell">$ terraform apply | <source lang="shell">$ terraform apply | ||
Line 348: | Line 348: | ||
+--------------------------------------+--------+--------+</pre> | +--------------------------------------+--------+--------+</pre> | ||
Dans ce résultat, trois instances précédemment créées ont survécu sans être touchées par Terraform. | |||
=== | === Récapitulation === | ||
Note there is now a file in your workspace called <code>terraform.tfstate</code>. This was created by Terraform during the application of the new configuration and confirmation of its success. The state file contains details about the managed resources Terraform uses to determine how to arrive at a new state described by configuration updates. In general, you will not need to look at this file, but know that without it, Terraform cannot properly manage resources and if you delete it, you will need to restore it or recreate it, or manage those resources without Terraform. | Note there is now a file in your workspace called <code>terraform.tfstate</code>. This was created by Terraform during the application of the new configuration and confirmation of its success. The state file contains details about the managed resources Terraform uses to determine how to arrive at a new state described by configuration updates. In general, you will not need to look at this file, but know that without it, Terraform cannot properly manage resources and if you delete it, you will need to restore it or recreate it, or manage those resources without Terraform. | ||
You now have a working VM which has successfully been initialized and is on the private network. You can’t log in and check it out however because you haven’t assigned a floating IP to this host, so it’s not directly accessible from outside the tenant. | You now have a working VM which has successfully been initialized and is on the private network. You can’t log in and check it out, however, because you haven’t assigned a floating IP to this host, so it’s not directly accessible from outside the tenant. | ||
If you had another host in that tenant with a floating IP, you could use that host as a jump host (sometimes called a | If you had another host in that tenant with a floating IP, you could use that host as a jump host (sometimes called a <i>bastion host</i>) to the new VM, as they will both be on the same private network. This is a good strategy to use for nodes that do not need to be directly accessible from the internet, such as a database server, or just to preserve floating IPs, which are a limited resource. | ||
Pour l'instant, ajoutez une IP flottante à votre nouvelle VM. | |||
== Ajouter une adresse IP flottante == | == Ajouter une adresse IP flottante == | ||
Une IP flottante n'est pas créée directement sur une VM OpenStack, mais est allouée au projet à partir d'un groupe d'IP et associée à l'iinterface du réseau privé de l'IP. | |||
Assuming you do not already have a floating IP allocated for this use, declare a | Assuming you do not already have a floating IP allocated for this use, declare a floating IP resource like the following example. The only thing you need is to know the pool from which to allocate the floating IP; on our clouds, this is the external network (<code>ext_net</code> in this example). | ||
<source lang="terraform">resource "openstack_networking_floatingip_v2" "myvm_fip" { | <source lang="terraform">resource "openstack_networking_floatingip_v2" "myvm_fip" { | ||
Line 370: | Line 370: | ||
}</source> | }</source> | ||
Acceptez ce changement maintenant ou utilisez <code>terraform plan</code> pour voir ce qui se produirait. | |||
<source lang="shell">$ terraform apply | <source lang="shell">$ terraform apply | ||
Line 408: | Line 408: | ||
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.</source> | Apply complete! Resources: 1 added, 0 changed, 0 destroyed.</source> | ||
Cette IP flottante est maintenant <i>allouée</i>, mais pas encore associée à votre instance. Ajoutez la définition suivante : | |||
<source lang="terraform">resource "openstack_compute_floatingip_associate_v2" "myvm_fip" { | <source lang="terraform">resource "openstack_compute_floatingip_associate_v2" "myvm_fip" { | ||
Line 415: | Line 415: | ||
}</source> | }</source> | ||
Les attributs de cette nouvelle ressource sont définies par des références à d'autres ressources et leurs attributs. | |||
<blockquote> | <blockquote><b>Note</b>: Current documentation of the OpenStack provider documentation uses syntax which differs from what is presented here as it has not yet been updated for changes to Terraform v.12. | ||
</blockquote> | </blockquote> | ||
References like this are typically <code><resource type>.<resource name>.<attribute></code>. Others you may soon see include <code>var.<variable name></code>. At any rate, this resource forms an association between the created earlier, and the floating IP allocated in the next step. | References like this are typically <code><resource type>.<resource name>.<attribute></code>. Others you may soon see include <code>var.<variable name></code>. At any rate, this resource forms an association between the created earlier, and the floating IP allocated in the next step. | ||
Line 455: | Line 455: | ||
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.</source> | Apply complete! Resources: 1 added, 0 changed, 0 destroyed.</source> | ||
S'il y a une IP flottante, vous pouvez probablement vous connecter à l'instance via SSH maintenant. | |||
<source lang="shell">$ ssh centos@X.Y.Z.W hostname | <source lang="shell">$ ssh centos@X.Y.Z.W hostname | ||
Line 464: | Line 464: | ||
myvm.novalocal</source> | myvm.novalocal</source> | ||
Autrement, il est possible que vous deveiz ajpouter l'adresse IP de votre ordinateur au groupe de sécurité par défaut du projet. | |||
== Ajouter un volume == | == Ajouter un volume == | ||
Next, add a root volume to the VM. Since this will replace its boot disk, | Next, add a root volume to the VM. Since this will replace its boot disk, <i>this is a destructive operation</i>. This is something you need to watch out for in Terraform, and one of the chief reasons for reading your plans carefully before applying. It’s unlikely you’re going to accidentally cause critical issues in creating new resources, but it can be deceptively easy to accidentally create configuration changes that require <i>rebuilding</i> existing VMs. | ||
Puisque c'est un volume racine, créez-le dans l'instance de calcul en tant que sous-bloc avec le sous-bloc du réseau. | |||
<source lang="terraform"> block_device { | <source lang="terraform"> block_device { | ||
Line 483: | Line 483: | ||
Set the <code>uuid</code> attribute to the UUID of the image you want to use and remove <code>image_id</code> from the outer block definition. The other attributes are self-explanatory, except for <code>destination_type</code>, which is here set to <code>volume</code> to indicate this is to be stored with an OpenStack-provided volume rather than using disk on the hypervisor. <code>delete_on_termination</code> is important—for testing, you will probably want this to be <code>true</code> so you don’t have to remember to constantly clean up leftover volumes, but for real use you should consider setting it to <code>false</code> as a last defence against accidental deletion of resources. | Set the <code>uuid</code> attribute to the UUID of the image you want to use and remove <code>image_id</code> from the outer block definition. The other attributes are self-explanatory, except for <code>destination_type</code>, which is here set to <code>volume</code> to indicate this is to be stored with an OpenStack-provided volume rather than using disk on the hypervisor. <code>delete_on_termination</code> is important—for testing, you will probably want this to be <code>true</code> so you don’t have to remember to constantly clean up leftover volumes, but for real use you should consider setting it to <code>false</code> as a last defence against accidental deletion of resources. | ||
<blockquote>Do | <blockquote>Do <i>not</i> leave the <code>image_id</code> attribute defined in the outer compute instance definition! This will work, but Terraform will see a change from “boot from volume” to “boot directly from image” on every run, and so will always attempt to rebuild your instance. (This is probably a flaw in the OpenStack provider.) | ||
</blockquote> | </blockquote> | ||
Here’s how the plan looks: | Here’s how the plan looks: | ||
Line 544: | Line 544: | ||
}</source> | }</source> | ||
Notez qu'il y a plusieurs avertissements qui vous informent de ce qui sera modifié, sans oublier | |||
<source lang="shell">Plan: 2 to add, 0 to change, 2 to destroy.</source> | <source lang="shell">Plan: 2 to add, 0 to change, 2 to destroy.</source> | ||
Your VM will be created with a new SSH key, so if you connected previously you'll need to remove the SSH key from your <code>known_hosts</code> file (or the equivalent). After this, the first thing to do is log on and | Your VM will be created with a new SSH key, so if you connected previously you'll need to remove the SSH key from your <code>known_hosts</code> file (or the equivalent). After this, the first thing to do is log on and <i>apply all available updates</i>. | ||
<source lang="shell">[centos@myvm ~]$ sudo yum update -y | <source lang="shell">[centos@myvm ~]$ sudo yum update -y | ||
Line 554: | Line 554: | ||
[ goes for ages ]</source> | [ goes for ages ]</source> | ||
Vous avez maintenant une VM terraformée fonctionnelle, un moyen d'y accéder, un endroit où enregistrer les données et les dernières mises à jour du système d'exploitation. | |||
== | == Exemple complet == | ||
<source lang="terraform">provider "openstack" { | <source lang="terraform">provider "openstack" { | ||
Line 596: | Line 596: | ||
The following might be of interest to those exploring further and building on the work done in this tutorial. Note that as of this writing the OpenStack provider’s documentation conforms to v0.11 syntax, but this should work under v0.12 without trouble. | The following might be of interest to those exploring further and building on the work done in this tutorial. Note that as of this writing the OpenStack provider’s documentation conforms to v0.11 syntax, but this should work under v0.12 without trouble. | ||
* [https://www.terraform.io/intro/index.html | * [https://www.terraform.io/intro/index.html What is Terraform?] | ||
* [https://www.terraform.io/docs/providers/openstack/index.html OpenStack | * [https://www.terraform.io/docs/providers/openstack/index.html OpenStack Provider] | ||
* [https://www.terraform.io/docs/providers/openstack/r/compute_instance_v2.html OpenStack compute instance | * [https://www.terraform.io/docs/providers/openstack/r/compute_instance_v2.html OpenStack compute instance v2] : plusieurs cas d'usage pour la création d'instances dans OpenStack avec Terraform | ||
* [[Cloud| | * [[Cloud/fr|Notre page wiki sur notre service infonuagique]] et la page [[Cloud Quick Start/fr|Cloud : Guide de démarrage]] | ||
=== Exemples === | === Exemples === | ||
* | * Projet [https://github.com/ComputeCanada/magic_castle Magic Castle] | ||
* [https://github.com/diodonfrost/terraform-openstack-examples diodonfrost/terraform-openstack-examples] | * [https://github.com/diodonfrost/terraform-openstack-examples diodonfrost/terraform-openstack-examples] sur GitHub | ||
=== Finding image and flavour UUIDs in Horizon === | === Finding image and flavour UUIDs in Horizon === | ||
For those more comfortable using the web interface to OpenStack, here is a quick cheat sheet on finding flavour and image UUIDs in Horizon. You’ll need to log into the web interface of the | For those more comfortable using the web interface to OpenStack, here is a quick cheat sheet on finding flavour and image UUIDs in Horizon. You’ll need to log into the web interface of the cloud for this information. | ||
To find an image’s UUID, find the | To find an image’s UUID, find the <i>Images</i> menu item under <i>Compute</i> (1). | ||
[[File:images-1.png|thumb|Find and select | [[File:images-1.png|thumb|Find and select an image]] | ||
Vous obtiendrez une liste des images disponibles pour votre projet. Cliquez sur celle que vous voulez utiliser. (2) | |||
[[File:images-2.png|thumb|Now you’ve got the UUID]] | [[File:images-2.png|thumb|Now you’ve got the UUID]] | ||
… et vous avez l'ID. | |||
C'est un peu plus compliqué pour les gabarits. | |||
For this you have to fake out launching an instance, but that doesn’t even give you the ID of the flavour. But at least you’ll know the | For this you have to fake out launching an instance, but that doesn’t even give you the ID of the flavour. But at least you’ll know the <i>name</i> of the flavour you want. | ||
[[File:flavour-1.png|thumb|Go to launch an instance]] | [[File:flavour-1.png|thumb|Go to launch an instance]] | ||
Once the launch dialog is open, select the | Once the launch dialog is open, select the <i>Flavor</i> pane. | ||
[[File:flavour-2.png|thumb|On the instance launch dialog select “Flavor”]] | [[File:flavour-2.png|thumb|On the instance launch dialog select “Flavor”]] | ||
Line 634: | Line 634: | ||
[[File:flavour-3.png|thumb|Select a flavour from the list]] | [[File:flavour-3.png|thumb|Select a flavour from the list]] | ||
Pour obtenir l'ID, il y a deux options : | |||
# Use the name for the first Terraform run, and then get the ID from the output or state file, and finally, switch your configuration to use the ID instead. This should not attempt to recreate the VM, but check before you agree to <code>terraform apply</code>. | # Use the name for the first Terraform run, and then get the ID from the output or state file, and finally, switch your configuration to use the ID instead. This should not attempt to recreate the VM, but check before you agree to <code>terraform apply</code>. | ||
# Switch to using the OpenStack CLI. (Recommended.) | # Switch to using the OpenStack CLI. (Recommended.) | ||
[[Category:Cloud]] | [[Category:Cloud]] |
Latest revision as of 15:44, 23 October 2023
Terraform est un outil qui permet de définir et d'approvisionner l'infrastructure de centres de données, y compris des machines virtuelles. Terraform est de plus en plus utilisé au sein de l'Alliance. Son modèle d'infrastructure-en-code permet de maintenir les ressources OpenStack comme une collection de définitions qui peuvent être facilement mises à jour à l'aide des éditeurs de texte, partagées entre les membres d'un groupe et stockées dans un système de contrôle de version.
Cette page est écrite comme un tutoriel dans lequel nous présentons Terraform et démontrons son utilisation sur nos nuages OpenStack. Nous configurons notre espace de travail local pour Terraform et créons une machine virtuelle (VM pour virtual machine) avec une IP flottante et un volume attaché.
Préparation
Avant de commencer avec Terraform, vous avez besoin
- d'un accès à un projet OpenStack avec des ressources disponibles,
- d'installer le binaire
terraform
, - d'effectuer quelques configurations sur votre poste de travail ou ordinateur portable.
Accéder à OpenStack
Pour accéder au nuage, voir Obtenir un projet dans l'environnement infonuagique sur le wiki de l'Alliance. Si vous n'avez jamais utilisé OpenStack auparavant, vous devriez d'abord vous familiariser avec ce système en créant une machine virtuelle, en attachant un volume, en associant une IP flottante et en vous assurant que vous pouvez vous connecter à la machine virtuelle par la suite. Ce tutoriel suppose également que vous avez déjà créé une paire de clés SSH et que la clé publique a été importée dans OpenStack.
Si vous ne savez pas encore comment faire cela, le Guide de démarrage est une bonne introduction. La création de ces ressources à l'aide de l'interface web d'OpenStack vous permettra de comprendre le fonctionnement et l'utilité de Terraform.
Installer Terraform
Consultez la page de téléchargement de Terraform pour obtenir la dernière version du binaire. Nous utilisons ici Terraform 0.12.
S'identifier pour OpenStack
There are two ways to provide your OpenStack credentials in a command-line environment: via environment variables or in a configuration file. We'll need to use one of these methods with Terraform, described in the next section. Regardless of your preferred method, the OpenStack web interface offers a simple way to download credentials: once logged in, click on API Access in the navigation bar, and on that page is a drop-down menu entitled “Download OpenStack RC File”. From here you may download a clouds.yaml
file or an RC file which can be sourced from your shell session.
Le fichier RC contient une liste de commandes pour l'interpréteur qui servent à exporter les variables d'environnement dans votre session active. Il ne s'agit pas d'un script indépendant et il doit recevoir de l'information par
$ source openrc.sh
Vous devez alors entrer votre mot de passe OpenStack qui sera enregistré dans une variable d'environnement préfixée par OS_
. D'autres variables d'environnement seront créées avec certains renseignements sur vous, votre projet et le nuage auquel vous voulez vous connecter, par exemple
The other method is to create a configuration in $HOME/.config/openstack/clouds.yaml
. If you don’t have such a file already, you can download `clouds.yaml` as described above and move it into place. We recommend changing the name given to the cloud in the downloaded file to something meaningful, especially if you use more than one OpenStack cloud. Then, to use the CLI tools described below, simply create an environment variable $OS_CLOUD
with the name of the cloud you want to use.
$ export OS_CLOUD=arbutus
Peu importe ce que vous choisissez, vous utiliserez ceci pour configurer Terraform.
Session OpenStack
It is helpful to have a terminal window open running the OpenStack CLI. This provides a handy reference for the specifications you will be building, as you will be looking up flavour and image IDs, and it is useful for verifying the actions performed by Terraform. Horizon can be used for looking up images, and for verifying in general that Terraform is having the intended effects, but it is not possible to directly lookup flavour IDs.
OpenStack CLI (aussi appelé OSC) est un client Python qui peut être installé avec Python Pip et qui ests disponibles pour plusieurs distribuitions et systèmes d'exploitation.
Espace de travail
Créez enfin un répertoire pour vos fichiers de configuration et d'état qui servira de point de départ.
Defining OpenStack provider
First, describe the provider: this is where you tell Terraform to use OpenStack, and how. On initialization the most recent version of the OpenStack provider plugin will be installed in the working directory and on subsequent Terraform operations, the included credentials will be used to connect to the specified cloud.
Your connection and credential information for OpenStack can be provided to Terraform in the specification, in the environment, or partially in the specification with the rest in the environment.
The following is an example of a provider specification with connection and credential information:
provider "openstack" {
tenant_name = "some_tenant"
tenant_id = "1a2b3c45678901234d567890fa1b2cd3"
auth_url = "https://cloud.example.org:5000/v3"
user_name = "joe"
password = "sharethiswithyourfriends!"
user_domain_name = "CentralID"
}
For some OpenStack instances, the above would specify the complete set of information necessary to connect to the instance and manage resources in the given project (“tenant”). However, Terraform supports partial credentials in which you could leave some values out of the Terraform configuration and supply them a different way. This would allow us, for example, to leave the password out of the configuration file, in which case it would need to be specified in the environment with $OS_PASSWORD
.
Alternatively, if you prefer to use clouds.yaml
, specify cloud
in the provider stanza:
provider "openstack" {
cloud = "my_cloud"
}
Il n'est pas nécessaire d'entrer une définition pour provider.
provider "openstack" {
}
In this case, either $OS_CLOUD
or the variables set by the appropriate RC file would need to be in the executing environment for Terraform to proceed.
The configuration reference of the OpenStack Provider describes the available options in detail.
Ce que vous devriez utiliser
It may be tempting to leave some of the details in the environment so that the Terraform configuration is more portable or reusable, but as we will see later, the Terraform configuration will and must contain details which are specific to each cloud, such as flavour and image UUIDs, network names, and tenants.
The most important consideration in what goes into your configuration in this regard is security. You probably want to avoid storing your credentials in the Terraform configuration, even if you’re not sharing it with anyone, even if it’s on your own workstation and nobody has access but you. Even if you’re not worried about hacking, it is definitely not good practice to store passwords and such in configuration files which may wind up getting copied and moved around your filesystem as you try things out. But also, always remember the “ABC” of Hacking: Always Be Concerned about Hacking!
Initialiser Terraform
To ensure we have the provider set up correctly, initialize Terraform and check the configuration so far. With the provider definition in a file called, for example, nodes.tf
, run terraform init
:
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "openstack" (terraform-providers/openstack)
1.19.0...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.openstack: version = "~> 1.19"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
This shows success in initializing Terraform and downloading the OpenStack provider plugin so the OpenStack stanzas will be handled correctly. This does not test out the credentials because this operation doesn’t actually try to connect to the defined provider.
Définir une VM
Définissions maintenant une VM de base.
Important: It is good practice to always specify flavours and images using their IDs even when Terraform supports using the name. Although the name is more readable, the ID is what actually defines the state of the resource and the ID of a given image or flavour will never change. It is possible, however, for the name to change. If a flavour or image is retired, for example, and replaced with another of the same name, the next time you run Terraform, the updated ID will be detected and Terraform will determine that you want to rebuild or resize the associated resource. This is a destructive (and reconstructive) operation.
A minimal OpenStack VM may be defined as follows in Terraform:
resource "openstack_compute_instance_v2" "myvm" {
name = "myvm"
image_id = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
key_pair = "Aluminum"
security_groups = ["default"]
}
Ceci crée une VM ayant le nom, l'image et le gabarit indiqués et associe la VM avec une paire de clés et le groupe de sécurité par défaut.
Note: If you’re following along (please do!), use your own values for
image_id
,flavor_id
, andkey_pair
, or this will probably fail!
The values for image_id
and flavor_id
are one reason I like to have a terminal session open running the OpenStack CLI, connected to the cloud I’m targeting with Terraform: I switch over to it and issue flavor list
or image list
. These list the names and IDs.
If using Horizon (the OpenStack web interface), this is semi-possible–see the guide in the appendix.
Note that no volumes are supplied. A compute instance on our clouds will already have an associated volume but a persistent instance will probably fail unless there is sufficient empty space in the image itself. It is recommended that a boot volume be created for VMs using persistent flavours.
Trying it out
La commande terraform plan
compile la définition de Terraform, tente de déterminer comment réconcilier l'état résultant avec l'état actuel du nuage et produit un plan des modifications qui s'appliqueraient.
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# openstack_compute_instance_v2.myvm will be created
+ resource "openstack_compute_instance_v2" "myvm" {
+ access_ip_v4 = (known after apply)
+ access_ip_v6 = (known after apply)
+ all_metadata = (known after apply)
+ availability_zone = (known after apply)
+ flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
+ flavor_name = (known after apply)
+ force_delete = false
+ id = (known after apply)
+ image_id = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
+ image_name = (known after apply)
+ key_pair = "Aluminum"
+ name = "myvm"
+ power_state = "active"
+ region = (known after apply)
+ security_groups = [
+ "default",
]
+ stop_before_destroy = false
+ network {
+ access_network = (known after apply)
+ fixed_ip_v4 = (known after apply)
+ fixed_ip_v6 = (known after apply)
+ floating_ip = (known after apply)
+ mac = (known after apply)
+ name = (known after apply)
+ port = (known after apply)
+ uuid = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Prenez connaissance du résultat. Même s'il contient beaucoup d'information, il est nécessaire d'en connaître le contenu avant d'accepter les modifications afin d'éviter les mauvaises surprises.
If you get an error about incomplete credentials, you may have forgotten to define
OS_CLOUD
or source the RC file, or yourclouds.yaml
file may be missing.
These values are to resources as they’d be defined in OpenStack. Anything marked known after apply
will be determined from the state of newly created resources queried from OpenStack. Other values are set according to what we’ve defined or determined by the Terraform and the OpenStack plugin as either calculated or default values.
Si vous n'avez pas le temps et que ce n'est pas grave de détruire accidentellement des ressources ou de les reconstruire, prenez au moins le temps de vérifier la dernière ligne du plan.
Plan: 1 to add, 0 to change, 0 to destroy.
In this case, we know we’re adding a resource so this looks right. If the other values were non-zero then we’d better have another look at our configuration, state and what’s actually defined in OpenStack and make whatever corrections are necessary.
Que se passe-t-il avec les ressources OpenStack déjà existantes?
Si des VM sont déjà définies dans votre projet OpenStack, vous vous demandez peut-être si Terraform affectera ces ressources.
Eh bien non. Terraform ne connait pas les ressources qui sont déjà définies pour le projet et n'essaie pas d'en déterminer l'état. Les actions de Terraform se basent sur la configuration fournie et sur l'état précédemment déterminé dans la configuration. Les ressources existantes ne sont pas représentées dans Terraform et lui sont invisibles.
It is possible to import previously defined OpenStack resources into Terraform but it is not a trivial amount of work and outside the scope of this tutorial. The important thing here is that any existing resources in your OpenStack project are safe from inadvertent mangling from Terraform—but just to be on the safe side, why don’t you make sure you read the output plans carefully? :)
Appliquer la configuration
Utilisez terraform apply
pour effectuer le changement décrit dans le plan.
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
[... repeat of the plan from above ...]
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
openstack_compute_instance_v2.myvm: Creating...
Error: Error creating OpenStack server: Expected HTTP response code [] when
accessing [POST
https://cloud.example.org:8774/v2.1/43b86742c5ee4eaf800a36d7d234d95c/servers],
but got 409 instead
{"conflictingRequest": {"message": "Multiple possible networks found, use a
Network ID to be more specific.", "code": 409}}
on nodes.tf line 4, in resource "openstack_compute_instance_v2" "myvm":
4: resource "openstack_compute_instance_v2" "myvm" {
Dans notre exemple, ceci échoue. Il y a au moins deux réseaux qui sont définis pour un projet OpenStack : un privé et un public. Terraform a besoin de savoir lequel utililser.
Ajouter un réseau
The name of the private network differs from project to project and the naming convention can differ from cloud to cloud, but typically they are on a 192.168.X.Y network, and can be found in the CLI using `network list` or on Horizon under Network -> Networks. If your project's private network is my-tenant-net
, you will add a network
resource sub-block to your VM definition similar to the following:
resource "openstack_compute_instance_v2" "myvm" {
name = "myvm"
image_id = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
key_pair = "Aluminum"
security_groups = ["default"]
network {
name = "my-tenant-net"
}
}
Essayez de nouveau.
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# openstack_compute_instance_v2.myvm will be created
+ resource "openstack_compute_instance_v2" "myvm" {
+ access_ip_v4 = (known after apply)
+ access_ip_v6 = (known after apply)
+ all_metadata = (known after apply)
+ availability_zone = (known after apply)
+ flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
+ flavor_name = (known after apply)
+ force_delete = false
+ id = (known after apply)
+ image_id = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
+ image_name = (known after apply)
+ key_pair = "Aluminum"
+ name = "myvm"
+ power_state = "active"
+ region = (known after apply)
+ security_groups = [
+ "default",
]
+ stop_before_destroy = false
+ network {
+ access_network = false
+ fixed_ip_v4 = (known after apply)
+ fixed_ip_v6 = (known after apply)
+ floating_ip = (known after apply)
+ mac = (known after apply)
+ name = "my-tenant-net"
+ port = (known after apply)
+ uuid = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
openstack_compute_instance_v2.myvm: Creating...
openstack_compute_instance_v2.myvm: Still creating... [10s elapsed]
openstack_compute_instance_v2.myvm: Still creating... [20s elapsed]
openstack_compute_instance_v2.myvm: Still creating... [30s elapsed]
openstack_compute_instance_v2.myvm: Creation complete after 32s [id=1f7f73ff-b9b5-40ad-9ddf-d848efe13e42]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
You now have a VM created by Terraform. You should see your new VM on Horizon or in the output of server list
in your OpenStack terminal window:
(openstack) server list -c ID -c Name -c Status +--------------------------------------+--------+--------+ | ID | Name | Status | +--------------------------------------+--------+--------+ | 1f7f73ff-b9b5-40ad-9ddf-d848efe13e42 | myvm | ACTIVE | | c3fa7d11-4122-412a-ad19-32e52cbb8f66 | store | ACTIVE | | f778f65f-c9d5-4808-930b-9f50d82a8c9c | puppet | ACTIVE | | 9b42cbf3-3782-4472-bdd0-9028bbb73460 | lbr | ACTIVE | +--------------------------------------+--------+--------+
Dans ce résultat, trois instances précédemment créées ont survécu sans être touchées par Terraform.
Récapitulation
Note there is now a file in your workspace called terraform.tfstate
. This was created by Terraform during the application of the new configuration and confirmation of its success. The state file contains details about the managed resources Terraform uses to determine how to arrive at a new state described by configuration updates. In general, you will not need to look at this file, but know that without it, Terraform cannot properly manage resources and if you delete it, you will need to restore it or recreate it, or manage those resources without Terraform.
You now have a working VM which has successfully been initialized and is on the private network. You can’t log in and check it out, however, because you haven’t assigned a floating IP to this host, so it’s not directly accessible from outside the tenant.
If you had another host in that tenant with a floating IP, you could use that host as a jump host (sometimes called a bastion host) to the new VM, as they will both be on the same private network. This is a good strategy to use for nodes that do not need to be directly accessible from the internet, such as a database server, or just to preserve floating IPs, which are a limited resource.
Pour l'instant, ajoutez une IP flottante à votre nouvelle VM.
Ajouter une adresse IP flottante
Une IP flottante n'est pas créée directement sur une VM OpenStack, mais est allouée au projet à partir d'un groupe d'IP et associée à l'iinterface du réseau privé de l'IP.
Assuming you do not already have a floating IP allocated for this use, declare a floating IP resource like the following example. The only thing you need is to know the pool from which to allocate the floating IP; on our clouds, this is the external network (ext_net
in this example).
resource "openstack_networking_floatingip_v2" "myvm_fip" {
pool = "ext_net"
}
Acceptez ce changement maintenant ou utilisez terraform plan
pour voir ce qui se produirait.
$ terraform apply
openstack_compute_instance_v2.myvm: Refreshing state...
[id=1f7f73ff-b9b5-40ad-9ddf-d848efe13e42]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# openstack_networking_floatingip_v2.myvm_fip will be created
+ resource "openstack_networking_floatingip_v2" "myvm_fip" {
+ address = (known after apply)
+ all_tags = (known after apply)
+ fixed_ip = (known after apply)
+ id = (known after apply)
+ pool = "provider-199-2"
+ port_id = (known after apply)
+ region = (known after apply)
+ tenant_id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
openstack_networking_floatingip_v2.myvm_fip: Creating...
openstack_networking_floatingip_v2.myvm_fip: Creation complete after 9s
[id=20190061-c2b6-4740-bbfc-6facbb300dd4]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Cette IP flottante est maintenant allouée, mais pas encore associée à votre instance. Ajoutez la définition suivante :
resource "openstack_compute_floatingip_associate_v2" "myvm_fip" {
floating_ip = openstack_networking_floatingip_v2.myvm_fip.address
instance_id = openstack_compute_instance_v2.myvm.id
}
Les attributs de cette nouvelle ressource sont définies par des références à d'autres ressources et leurs attributs.
Note: Current documentation of the OpenStack provider documentation uses syntax which differs from what is presented here as it has not yet been updated for changes to Terraform v.12.
References like this are typically <resource type>.<resource name>.<attribute>
. Others you may soon see include var.<variable name>
. At any rate, this resource forms an association between the created earlier, and the floating IP allocated in the next step.
$ terraform apply
openstack_networking_floatingip_v2.myvm_fip: Refreshing state...
[id=20190061-c2b6-4740-bbfc-6facbb300dd4]
openstack_compute_instance_v2.myvm: Refreshing state...
[id=1f7f73ff-b9b5-40ad-9ddf-d848efe13e42]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# openstack_compute_floatingip_associate_v2.myvm_fip will be created
+ resource "openstack_compute_floatingip_associate_v2" "myvm_fip" {
+ floating_ip = "X.Y.Z.W"
+ id = (known after apply)
+ instance_id = "1f7f73ff-b9b5-40ad-9ddf-d848efe13e42"
+ region = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
openstack_compute_floatingip_associate_v2.myvm_fip: Creating...
openstack_compute_floatingip_associate_v2.myvm_fip: Creation complete after 5s
[id=X.Y.Z.W/1f7f73ff-b9b5-40ad-9ddf-d848efe13e42/]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
S'il y a une IP flottante, vous pouvez probablement vous connecter à l'instance via SSH maintenant.
$ ssh centos@X.Y.Z.W hostname
The authenticity of host 'X.Y.Z.W (X.Y.Z.W)' can't be established.
ECDSA key fingerprint is SHA256:XmN5crnyxvE1sezdpo5tG5Z2nw0Z+2pspvkNSGpB99A.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'X.Y.Z.W' (ECDSA) to the list of known hosts.
myvm.novalocal
Autrement, il est possible que vous deveiz ajpouter l'adresse IP de votre ordinateur au groupe de sécurité par défaut du projet.
Ajouter un volume
Next, add a root volume to the VM. Since this will replace its boot disk, this is a destructive operation. This is something you need to watch out for in Terraform, and one of the chief reasons for reading your plans carefully before applying. It’s unlikely you’re going to accidentally cause critical issues in creating new resources, but it can be deceptively easy to accidentally create configuration changes that require rebuilding existing VMs.
Puisque c'est un volume racine, créez-le dans l'instance de calcul en tant que sous-bloc avec le sous-bloc du réseau.
block_device {
uuid = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
source_type = "image"
destination_type = "volume"
volume_size = 10
boot_index = 0
delete_on_termination = true
}
Set the uuid
attribute to the UUID of the image you want to use and remove image_id
from the outer block definition. The other attributes are self-explanatory, except for destination_type
, which is here set to volume
to indicate this is to be stored with an OpenStack-provided volume rather than using disk on the hypervisor. delete_on_termination
is important—for testing, you will probably want this to be true
so you don’t have to remember to constantly clean up leftover volumes, but for real use you should consider setting it to false
as a last defence against accidental deletion of resources.
Do not leave the
image_id
attribute defined in the outer compute instance definition! This will work, but Terraform will see a change from “boot from volume” to “boot directly from image” on every run, and so will always attempt to rebuild your instance. (This is probably a flaw in the OpenStack provider.)
Here’s how the plan looks:
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# openstack_compute_floatingip_associate_v2.myvm_fip must be replaced
-/+ resource "openstack_compute_floatingip_associate_v2" "myvm_fip" {
floating_ip = "199.241.167.122"
~ id = "199.241.167.122/1f7f73ff-b9b5-40ad-9ddf-d848efe13e42/" -> (known after apply)
~ instance_id = "1f7f73ff-b9b5-40ad-9ddf-d848efe13e42" -> (known after apply) # forces replacement
~ region = "RegionOne" -> (known after apply)
}
# openstack_compute_instance_v2.myvm must be replaced
-/+ resource "openstack_compute_instance_v2" "myvm" {
~ access_ip_v4 = "192.168.2.11" -> (known after apply)
+ access_ip_v6 = (known after apply)
~ all_metadata = {} -> (known after apply)
~ availability_zone = "nova" -> (known after apply)
flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
~ flavor_name = "p1-3gb" -> (known after apply)
force_delete = false
~ id = "1f7f73ff-b9b5-40ad-9ddf-d848efe13e42" -> (known after apply)
image_id = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
~ image_name = "CentOS-7-x64-2018-05" -> (known after apply)
key_pair = "Aluminum"
name = "myvm"
power_state = "active"
~ region = "RegionOne" -> (known after apply)
security_groups = [
"default",
]
stop_before_destroy = false
+ block_device {
+ boot_index = 0 # forces replacement
+ delete_on_termination = true # forces replacement
+ destination_type = "volume" # forces replacement
+ source_type = "image" # forces replacement
+ uuid = "80ceebef-f9aa-462e-a793-d3c1cf96123b" # forces replacement
+ volume_size = 10 # forces replacement
}
~ network {
access_network = false
~ fixed_ip_v4 = "192.168.2.11" -> (known after apply)
+ fixed_ip_v6 = (known after apply)
+ floating_ip = (known after apply)
~ mac = "fa:16:3e:3b:79:27" -> (known after apply)
name = "my-tenant-net"
+ port = (known after apply)
~ uuid = "5c96bf54-a396-47c5-ab12-574f630bcb80" -> (known
after apply)
}
}
Notez qu'il y a plusieurs avertissements qui vous informent de ce qui sera modifié, sans oublier
Plan: 2 to add, 0 to change, 2 to destroy.
Your VM will be created with a new SSH key, so if you connected previously you'll need to remove the SSH key from your known_hosts
file (or the equivalent). After this, the first thing to do is log on and apply all available updates.
[centos@myvm ~]$ sudo yum update -y
...
[ goes for ages ]
Vous avez maintenant une VM terraformée fonctionnelle, un moyen d'y accéder, un endroit où enregistrer les données et les dernières mises à jour du système d'exploitation.
Exemple complet
provider "openstack" {
}
resource "openstack_compute_instance_v2" "myvm" {
name = "myvm"
flavor_id = "0351ddb0-00d0-4269-80d3-913029d1a111"
key_pair = "Aluminum"
security_groups = ["default"]
network {
name = "my-tenant-net"
}
block_device {
uuid = "80ceebef-f9aa-462e-a793-d3c1cf96123b"
source_type = "image"
destination_type = "volume"
volume_size = 10
boot_index = 0
delete_on_termination = true
}
}
resource "openstack_networking_floatingip_v2" "myvm_fip" {
pool = "provider-199-2"
}
resource "openstack_compute_floatingip_associate_v2" "myvm_fip" {
floating_ip = openstack_networking_floatingip_v2.myvm_fip.address
instance_id = openstack_compute_instance_v2.myvm.id
}
Annexe
Références
The following might be of interest to those exploring further and building on the work done in this tutorial. Note that as of this writing the OpenStack provider’s documentation conforms to v0.11 syntax, but this should work under v0.12 without trouble.
- What is Terraform?
- OpenStack Provider
- OpenStack compute instance v2 : plusieurs cas d'usage pour la création d'instances dans OpenStack avec Terraform
- Notre page wiki sur notre service infonuagique et la page Cloud : Guide de démarrage
Exemples
- Projet Magic Castle
- diodonfrost/terraform-openstack-examples sur GitHub
Finding image and flavour UUIDs in Horizon
For those more comfortable using the web interface to OpenStack, here is a quick cheat sheet on finding flavour and image UUIDs in Horizon. You’ll need to log into the web interface of the cloud for this information.
To find an image’s UUID, find the Images menu item under Compute (1).
Vous obtiendrez une liste des images disponibles pour votre projet. Cliquez sur celle que vous voulez utiliser. (2)
… et vous avez l'ID.
C'est un peu plus compliqué pour les gabarits.
For this you have to fake out launching an instance, but that doesn’t even give you the ID of the flavour. But at least you’ll know the name of the flavour you want.
Once the launch dialog is open, select the Flavor pane.
Now you should have a list of flavours and it’ll also show you which ones fit within your quotas. All you’ve got here is the name, though.
Pour obtenir l'ID, il y a deux options :
- Use the name for the first Terraform run, and then get the ID from the output or state file, and finally, switch your configuration to use the ID instead. This should not attempt to recreate the VM, but check before you agree to
terraform apply
. - Switch to using the OpenStack CLI. (Recommended.)