Voici un tutoriel détaillé sur comment fonctionne CloudFormation et une analyse d’un modèle qui crée un Cloud privé virtuel VPC.
Dans cet article, nous allons apprendre un peu plus sur CloudFormation. Grâce à un modèle que nous avons écrit, vous pouvez créer un cloud privé virtuel (VPC) et le faire fonctionner vous-même.
Commençons !
À lire aussi
Que comprend le modèle CloudFormation ?
Voici un modèle CloudFormation super simple qui crée un compartiment S3 :
AWSTemplateFormatVersion: 2010-09-09
Description: Bucket Stack
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket
Vous pouvez créer des modèles CloudFormation en utilisant JSON ou YAML. Nous préférons ce dernier, donc tous les modèles inclus dans cet article sont en YAML.
Quel que soit votre choix, les modèles peuvent être constitués des principales sections d’informations que nous expliquons ci-dessous. Toutefois, la section Ressources étant la seule obligatoire.
Version de format (facultative)
Il s’agit de la version du modèle AWS CloudFormation à laquelle votre modèle est conforme et identifie les capacités du modèle. Ce n’est pas la même chose que la version API ou WSDL.
Au moment de la rédaction de cet article, la dernière et seule version valide du modèle est celle de 2010-09-09.
Bien qu’il n’y ait qu’une seule version valide pour le moment et que ce champ soit facultatif, c’est une bonne idée de l’inclure dans vos modèles pour référence future.
Description (facultative)
Cette section comprend une chaîne de texte qui fournit au lecteur une brève description (de 0 à 1024 octets) du modèle. Elle doit apparaître juste après la section Format de la version.
Soyez descriptif, mais court !
Métadonnées (facultatives)
Cette section n’est pas souvent utilisée, mais vous pouvez y ajouter plus d’informations sur votre modèle.
Il peut s’agir des outils tiers que vous pouvez utiliser pour générer et modifier ces modèles et d’autres données générales.
Veuillez noter que la section Métadonnées ne doit pas être confondue avec l‘attribut Métadonnées qui relève de la section Ressources. Cette section Métadonnées doit contenir des informations sur le modèle dans son ensemble. À l’encontre, l’attribut Métadonnées doit inclure des données sur une ressource spécifique.
Paramètres (facultatifs)
Vous pouvez utiliser la section Paramètres pour ajouter des valeurs personnalisées dans votre modèle. Cela est fait lorsque vous créez ou mettez à jour une pile afin de rendre ces modèles portables pour une utilisation dans d’autres projets.
À titre d’exemple, vous pouvez créer des paramètres qui spécifient le suivant:
- Le type d’instance EC2 à utiliser,
- Un nom de compartiment S3,
- Une plage d’adresses IP et
- D’autres propriétés qui peuvent être importantes pour votre pile.
Les sections Ressources et Sorties se réfèrent souvent aux Paramètres. Ces références doivent être ajoutées dans le même modèle.
Mappages (facultatifs)
La section Mappages vous permet de créer des dictionnaires de valeurs-clés pour spécifier les valeurs des paramètres conditionnels.
Exemples : le déploiement de différentes AMIs pour chaque région AWS, ou le mappage de différents groupes de sécurité aux environnements Dev, Test, QA et Prod qui partagent d’une autre manière la même pile d’infrastructure.
Pour récupérer des valeurs dans une mappe, vous utilisez la fonction intrinsèque « FN::FindInMap » dans les sections Ressources et Sorties.
Conditions (facultatives)
Les conditions vous permettent d’utiliser des instructions logiques (tout comme une instruction « si alors ») pour déclarer ce qui doit se passer dans certaines situations.
Nous avons mentionné un exemple ci-dessus concernant les environnements Dev, Test, QA et Prod.
Dans cet exemple, vous pouvez utiliser des conditions pour spécifier le type d’instance EC2 à déployer dans chacun de ces environnements.
Si l’environnement est Prod, vous pouvez définir l’instance EC2 sur m4.large. Si l’environnement est Test, vous pouvez le définir sur t2.micro pour économiser de l’argent.
Transformation (facultative)
La section Transformation vous permet de simplifier votre modèle CloudFormation. Cela se fait en condensant plusieurs lignes de code de déclaration de ressource et en réutilisant les composants du modèle.
Le CloudFormation prend en charge deux types de transformations :
- « AWS::Include » se réfère aux extraits de modèle stockés séparément en modèle CloudFormation principal avec lequel vous travaillez.
Ainsi, vous pouvez faire des déclarations de ressources sur plusieurs lignes dans des fichiers YAML ou JSON stockés ailleurs. Ensuite, vous y référer avec une seule ligne de code dans votre modèle CloudFormation principal. - « AWS::Serverless » spécifie la version du modèle d’application AWS Serverless (SAM) à utiliser et comment il est traité.
Vous pouvez déclarer plusieurs transformations dans un modèle et CloudFormation les exécute dans l’ordre spécifié.
Vous pouvez également utiliser des extraits de modèle sur plusieurs modèles CloudFormation.
Ressources (obligatoires)
La section Ressources est la seule section obligatoire dans un modèle CloudFormation.
Dans cette section, vous déclarez les ressources AWS, telles que:
- Les instances EC2,
- Les compartiments S3,
- Les clusters Redshift
- et autres, que vous voulez déployer dans votre pile.
Vous spécifiez aussi les propriétés, telles que la taille de l’instance, les rôles IAM et le nombre de nœuds, pour chacun de ces composants.
C’est la section qui occupera la majeure partie de vos modèles.
Sorties (facultatives)
Dans la section Sorties, vous décrivez les valeurs qui sont renvoyées lorsque vous voulez afficher les propriétés de votre pile.
Vous pouvez exporter ces sorties pour les utiliser dans d’autres piles. Il est aussi possible de les afficher simplement sur la console CloudFormation ou CLI comme un moyen pratique d’obtenir des informations importantes sur les composants de votre pile.
Il y a beaucoup d’informations à comprendre sur les sections CloudFormation. Tout cela deviendra plus clair au fur et à mesure que nous parcourrons réellement certains modèles. C’est ce que nous allons faire maintenant.
Créer un VPC avec AWS CloudFormation
Le modèle que nous avons fourni ci-dessous crée un cloud privé virtuel (VPC) avec des sous-réseaux publics et privés. Ceci vous permettra de lancer des ressources AWS dans un réseau virtuel que vous définissez et que vous contrôlez entièrement.
Dans ce modèle, nous créons un VPC avec un sous-réseau public pour vos serveurs Web qui sont publiquement adressables. De plus, nous aurons un sous-réseau privé où vos composants backend dont les bases de données ou les serveurs d’applications seront stockés et à l’abri des regards indiscrets sur Internet.
Le sous-réseau public se connecte à Internet via une passerelle Internet. Une table de routage indique au sous-réseau public comment trouver la passerelle Internet.
Nous allons ensuite répliquer les sous-réseaux publics et privés dans une autre zone de disponibilité pour une haute disponibilité.
Ce modèle est assez simple et ne contient que les sections Version de format, Description et Ressources.
Voici le modèle CloudFormation dans son intégralité :
AWSTemplateFormatVersion: 2010-09-09
Description: Creates a VPC with public and private subnets
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 192.168.101.0/24
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.0/28
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.32/28
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
PublicRouteTable:
DependsOn: AttachGateway
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
PublicDefaultRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
RouteTableId: !Ref PublicRouteTable
PublicRouteAssociationA:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetA
PublicSubnetB:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.16/28
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.48/28
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
PublicRouteAssociationB:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetB
OK ! Allons examiner ce qui se passe ici.
Créer un VPC et des sous-réseaux publics et privés
Tout d’abord, nous ajoutons un VPC qui englobe l’ensemble du réseau que nous sommes sur le point de créer :
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 192.168.101.0/24
Voilà ce qui se passe :
- VPC : c’est le nom que vous donnez à la ressource.
- Type : définit le type de ressource CloudFormation. Consultez la documentation des types de ressources pour trouver les propriétés prises en charge.
- Propriétés : chaque ressource a des propriétés obligatoires et facultatives. Dans ce cas, vous pouvez définir la plage d’adresses IP en notation CIDR.
Ensuite, nous ajoutons un sous-réseau public et privé :
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.0/28
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.32/28
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
Comme précédemment, vous remarquerez la même structure de ressources de nom, type et propriétés prises en charge. Le type « AWS::EC2::Subnet » prend en charge quelques propriétés supplémentaires.
L’exemple ci-dessus utilise également une syntaxe spéciale pour rendre le modèle un peu plus dynamique, telle que :
Pseudo paramètres
Un pseudo-paramètre se résout dynamiquement en une valeur, compte tenu du contexte de la pile CloudFormation.
A titre d’exemple, « Ref: AWS::Region » est converti dans la région dans laquelle vous déployez le modèle (c’est-à-dire us-east-1).
Fonctions intrinsèques
Un modèle CloudFormation est une configuration, pas un code. Cependant, vous avez accès à une logique d’exécution de base.
Dans l’exemple ci-dessus, « !GetAZs Ref: AWS::Region » a toutes les zones de disponibilité dans la région actuelle. Et la fonction « !Select » a le premier AZ de la liste.
Une autre utilisation d’une fonction intrinsèque est « !Ref VPC ». Celle-ci a l’ID VPC de la ressource VPC définie précédemment.
Voici un aperçu de ce qui se passe dans le code ci-dessus :
- PublicSubnetA est notre sous-réseau public et toutes les instances EC2 provisionnées recevront une adresse IP publique.
- PrivateSubnetA est notre sous-réseau privé.
- Chaque sous-réseau est provisionné dans la première zone de disponibilité de la région actuelle. Par exemple, cela pourrait être « us-east-1a ».
- Chaque sous-réseau est placé à l’intérieur du VPC défini précédemment.
- La plage d’adresses IP de chaque sous-réseau contient 16 adresses. Ces plages ne se chevauchent pas et se situent dans la plage IP globale du VPC.
Nous nous retrouvons avec cette architecture :
Ajouter une passerelle Internet et une table de routage
Ensuite, nous créons une passerelle Internet. Cela permet aux instances dans VPC d’accéder à Internet. Elle permet aussi à Internet d’accéder aux serveurs du sous-réseau public :
InternetGateway:
Type: AWS::EC2::InternetGateway
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
Dans les coulisses, la passerelle Internet n’a aucun moyen de s’associer à notre VPC. Vous devez donc créer une ressource « AWS::EC2:: VPCGatewayAttachment » pour effectuer cette tâche.
Ensuite, nous créons une table de routage, ainsi que quelques ressources connexes :
PublicRouteTable:
DependsOn: AttachGateway
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
PublicDefaultRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
RouteTableId: !Ref PublicRouteTable
PublicRouteAssociationA:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetA
La Table de Routage n’a qu’une seule propriété, « VpcId: !Ref VPC », qui s’associe à un VPC.
Les ressources Route (« AWS::EC2::Route ») contiennent une seule route, qui pointe une plage d’adresses IP vers une passerelle. La Route s’associe à la Table de Route.
Une Association de Table de Routage de Sous-réseau relie la table de routage à un sous-réseau. Dans ce cas, la table de routage dirige tout le trafic de PublicSubnetA vers Internet.
Il faut noter l’attribut « DependsOn ». En principe, CloudFormation est plutôt bon pour faire tourner les dépendances dans le bon ordre. Cependant, vous pouvez utiliser l’attribut « DependsOn » pour définir explicitement une dépendance.
Cette architecture montre l’ajout de la Passerelle Internet et de la Table de Routage :
Répliquer les sous-réseaux pour une haute disponibilité
Enfin, nous répliquons les sous-réseaux dans une nouvelle zone de disponibilité pour faciliter la haute disponibilité.
PublicSubnetB:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.16/28
MapPublicIpOnLaunch: true
VpcId: !Ref VPC
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: AWS::Region
CidrBlock: 192.168.101.48/28
MapPublicIpOnLaunch: false
VpcId: !Ref VPC
PublicRouteAssociationB:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnetB
C’est à peu près la même chose que ce que nous avons déjà créé pour les sous-réseaux publics et privés A.
Comme précédemment, les plages d’adresses IP sont uniques et ne se chevauchent pas. La principale différence avec l’ensemble B est qu’ils sont provisionnés dans la deuxième zone de disponibilité plutôt que dans la première.
Il faut noter que PublicSubnetB a besoin de sa propre association de route, car il s’agit d’une association par sous-réseau.
Enfin, vous vous retrouvez avec cette jolie architecture VPC :
Vous avez maintenant l’infrastructure réseau pour lancer des instances EC2, des bases de données ou d’autres ressources AWS avec une sécurité de base ! Vous pouvez utiliser ce modèle comme point de départ pour de futurs projets.
Ou vous pouvez télécharger tous ces articles ensemble dans un eBook pratique en cliquant sur le lien ci-dessous. Merci d’avoir lu !