Dans le post précédent, vous avez appris à déployer une application Spring Boot Dockerized de base sur AWS Fargate. Ne serait-il pas formidable que cette configuration manuelle puisse être fournie à partir d’un fichier texte brut pouvant faire partie de votre système de contrôle de version ? En une seule action, toutes les ressources nécessaires sont configurées dans le bon ordre. Dans cet article, vous apprendrez à créer un modèle AWS CloudFormation. Prendre plaisir!
1. Introduction
Il est conseillé de lire le post précédent d’abord car dans cet article, vous exécuterez les étapes identiques mais cette fois les étapes sont configurées dans un modèle CloudFormation. Cependant, si vous savez déjà ce qu’est AWS Fargate, vous pouvez l’ignorer et commencer tout de suite. Avec CloudFormation, la configuration de votre infrastructure peut être provisionnée facilement et l’infrastructure peut être traitée comme du code. Bien entendu, le provisionnement sera facile une fois que vous aurez correctement configuré le modèle. Ce dernier peut être tout un défi, mais la documentation et les exemples AWS vous aideront tout au long du processus. La preuve du pudding est dans le fait de manger, alors voyons comment la configuration du post précédent, où vous avez déployé une application Spring Boot sur AWS Fargate, peut être transformée en un modèle CloudFormation. Vous le ferez étape par étape, car le modèle complet peut être écrasant au début.
Les sources utilisées dans ce blog sont disponibles sur GitHub. Les modèles utilisés sont présents dans le répertoire cf_templates
.
2. Créez l’application
L’application Spring Boot est une application de base avec un point de terminaison Hello Rest qui renvoie un message de bienvenue comprenant l’hôte sur lequel l’application est en cours d’exécution. L’application est utilisée avant dans un post précédent. Le contrôleur est le suivant :
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
String message = "Hello AWS!";
try {
InetAddress ip = InetAddress.getLocalHost();
message += " From host: " + ip;
} catch (UnknownHostException e) {
e.printStackTrace();
}
return message;
}
}
Un Dockerfile est disponible à la racine du référentiel et le dockerfile-maven-plugin
est ajouté à la pom
déposer.
Exécutez la compilation afin de créer le fichier jar et l’image Docker correspondante.
Vérifiez si l’image Docker est disponible dans votre référentiel Docker local.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mydeveloperplanet/myawsplanet 0.0.1-SNAPSHOT 765984f7cfc2 24 seconds ago 666MB
3. Télécharger l’image dans ECR
Maintenant que vous avez créé l’image Docker, vous devez la télécharger dans ECR, le référentiel AWS Docker. Naviguez dans AWS jusqu’au service ECS et sélectionnez dans le menu de gauche le Dépôts section. La première chose à faire est de créer un référentiel en cliquant sur le Créer un référentiel bouton.
Donnez au référentiel un nom reconnaissable comme mydeveloperplanet/myawsplanet et cliquez Créer un référentiel bouton.Afin de voir comment vous pouvez pousser l’image Docker vers le référentiel, cliquez sur le bouton Afficher les commandes push qui est disponible dans la vue d’ensemble du référentiel.
Exécutez l’étape 1, qui vous fournira des informations d’identification temporaires afin de pouvoir accéder au référentiel. Les
<account ID>
doit être remplacé par votre ID de compte AWS.
$ aws ecr get-login-password --region eu-west-3 | docker login --username AWS --password-stdin <account ID>.dkr.ecr.eu-west-3.amazonaws.com
Ignorez l’étape 2, la construction de l’image Docker est déjà exécutée au moyen de la construction Maven. A l’étape 3, ajustez la commande afin d’utiliser la version 0.0.1-SNAPSHOT
à la place de latest
pour identifier l’image Docker locale.
$ docker tag mydeveloperplanet/myawsplanet:0.0.1-SNAPSHOT <account ID>.dkr.ecr.eu-west-3.amazonaws.com/mydeveloperplanet/myawsplanet:latest
À l’étape 4, vous transférez l’image Docker locale vers le référentiel AWS Docker distant.
$ docker push <account ID>.dkr.ecr.eu-west-3.amazonaws.com/mydeveloperplanet/myawsplanet:latest
Une fois le téléchargement réussi, l’image Docker est visible dans le référentiel.
4. Ajouter une définition de tâche
La première chose à faire est de créer le modèle yaml CloudFormation. Vous pouvez le faire au moyen d’un éditeur de texte, mais lorsque vous utilisez IntelliJ, vous pouvez également utiliser le plug-in AWS CloudFormation. Ce plugin vous donnera des fonctionnalités de validation et de saisie semi-automatique qui peuvent être très pratiques lors de l’écriture du modèle yaml. La création du fichier yaml avec IntelliJ peut être effectuée en cliquant avec le bouton droit sur le projet, choisissez Nouveau, et sélectionnez Modèle YAML AWS CloudFormation.
La configuration de la définition de la tâche est présente dans le cf_templates/template_task_definition.yaml
fichier dans le référentiel. La documentation AWS officielle pour la création de la définition de tâche sera la principale source d’informations. Créez une définition de tâche dans le Resources
section.
Définir la propriété RequiresCompatibilities
à FARGATE
car bien sûr, vous exécuterez la tâche dans un cluster Fargate.
Resources:
MyTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- "FARGATE"
L’image Docker que vous devez utiliser est présente dans le registre ECR. Afin de pouvoir accéder au registre, un rôle d’exécution de tâche est nécessaire. Ce rôle ne doit être créé qu’une seule fois. Pour simplifier, on suppose que ce rôle existe déjà. Sinon, consultez la documentation AWS. Accédez au service IAM et choisissez Les rôles dans le menu de gauche. Rechercher ecs dans la barre de recherche. Clique le ecsTaskExecutionRole
et copiez le ARN
.
Ajouter le rôle dans le Properties
section.
Properties:
...
ExecutionRoleArn: "arn:aws:iam::<replace with account ID>:role/ecsTaskExecutionRole"
Définissez le CPU de la tâche sur 256, ce qui correspond à 0,25 vCPU et définissez la mémoire de la tâche sur 512, ce qui correspond à 0,5 Go. Les deux paramètres sont requis lorsque la tâche est déployée sur un cluster Fargate.
Met le NetworkMode
à awsvpc
. Cette valeur doit être explicitement définie pour Fargate car la valeur par défaut est bridge
.
La définition de conteneur doit contenir le nom et l’image de l’image Docker que vous souhaitez exécuter. L’image doit faire référence à l’URI de l’image dans le référentiel ECR.
Définir la limite logicielle (MemoryReservation
) et limite stricte (Memory
) à respectivement 256 et 512.
Enfin, définissez le mappage de port sur 8080 puisque l’application Spring Boot s’exécute sur le port 8080 dans le conteneur. N’oubliez pas qu’il n’est pas nécessaire de définir un port hôte, Fargate s’en chargera.
La définition complète de la tâche est la suivante :
AWSTemplateFormatVersion: "2010-09-09"
Description: "CloudFormation template for creating a task definition"
Resources:
MyTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- "FARGATE"
ExecutionRoleArn: "arn:aws:iam::<replace with account ID>:role/ecsTaskExecutionRole"
Cpu: 256
Memory: 512
NetworkMode: "awsvpc"
ContainerDefinitions:
- Name: "myawsplanet"
Image: "<replace with account ID>.dkr.ecr.eu-west-3.amazonaws.com/mydeveloperplanet/myawsplanet:latest"
MemoryReservation: 256
Memory: 512
PortMappings:
- ContainerPort: 8080
Protocol: tcp
5. Créer une pile
Maintenant que vous avez créé la définition de tâche, il serait intéressant de voir si cela fonctionne réellement. Par conséquent, vous devez créer une pile dans CloudFormation. Accédez au service CloudFormation et cliquez sur le Créer une pile bouton.
À l’étape 1, sélectionnez Télécharger un fichier modèle et accédez au modèle sur votre ordinateur local. Clique le Prochain bouton. À ce stade, une certaine validation du modèle est effectuée. Par exemple, lorsque l’erreur [/Description] 'null' values are not allowed in templates
est montré, le Description
le champ à la ligne 2 est vide.
À l’étape 2, donnez à la pile le nom MyFirstStack et cliquez sur le Prochain bouton.
À l’étape 3, cliquez sur le Prochain bouton. À l’étape 4, vous avez la possibilité de tout revoir et lorsque cela semble correct, cliquez sur le bouton Créer une pile bouton. Dans le Événements onglet de la pile, la progression de la création de la pile peut être suivie.
Accédez au service ECS et cliquez sur Définitions des tâches dans le menu de gauche. Vérifiez si la définition de tâche a été créée.
6. Ajouter un cluster
La configuration du cluster est présente dans le cf_templates/template_cluster.yaml
fichier dans le référentiel. Ce fichier commence à partir du template_task_definition.yaml
fichier dans lequel vous ajouterez la configuration du cluster. La documentation officielle AWS pour la création du cluster ECS sera la principale source d’informations. Créer un cluster ECS dans le Resources
section et donnez-lui le nom MyFargateCluster
.
ECSCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: MyFargateCluster
Accédez à la pile et cliquez sur le Mettre à jour bouton.
À l’étape 1, choisissez Remplacer le modèle actuel et télécharger le fichier template_cluster.yaml
.
Dans les étapes suivantes, cliquez simplement sur le Prochain bouton jusqu’au Revoir étape. Clique le Mettre à jour la pile bouton et regardez le Événements onglet pour une création réussie.
Accédez au service ECS et vérifiez si le cluster est créé.
7. Ajouter ALB
Pour créer un service qui exécutera la tâche, un équilibreur de charge d’application (ALB) est nécessaire. La configuration de l’ALB est présente dans le cf_templates/template_alb.yaml
fichier dans le référentiel. Ce fichier commence à partir du template_cluster.yaml
dans lequel vous ajouterez la configuration ALB. La documentation officielle d’AWS pour la création de l’ALB sera la principale source d’informations. N’utilisez pas cette documentation AWS car celle-ci est destinée à un Classic Load Balancer et ce n’est pas ce dont vous avez besoin ici. Créer un ALB dans le Resources
section et donnez-lui le nom FargateAlb
.
La configuration ALB nécessite la configuration des sous-réseaux à utiliser. Pour plus de simplicité, vous utiliserez le VPC par défaut. Accédez au service VPC et cliquez sur Sous-réseaux dans le menu de gauche. Colonne ID de sous-réseau vous montrera les identifiants qui peuvent être utilisés.La configuration jusqu’à présent se présente comme suit. A noter que le
Type
est réglé sur application
. Il n’est pas vraiment nécessaire de définir cela car l’application est la valeur par défaut, mais cela ne fait pas de mal d’être explicite dans ce que vous faites.
FargateAlb:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
Name: FargateAlb
Subnets:
- subnet-580b0331
- subnet-7102210a
- subnet-c40f7b89
Type: application
Ajouter un groupe cible MyFargateTargetGroup
. La configuration correspond au paragraphe Service et la partie Conteneur à charger dans le post précédent. Les VpcId
est récupéré à partir du service VPC et de la section Vos VPC dans le menu de gauche. En cliquant sur le VPC, vous verrez l’ID.
MyFargateTargetGroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
Name: MyFargateTargetGroup
VpcId: vpc-9d55b7f5
Protocol: HTTP
Port: 8080
HealthCheckPath: /actuator/
TargetType: ip
Ajoutez l’écouteur pour l’ALB. Vous souhaitez acheminer tout le trafic de l’ALB vers le groupe cible spécifié de type forward
. Ceci est expliqué dans la documentation AWS. Dans ce cas, le TargetGroupArn
doit faire référence au groupe cible créé ci-dessus. Ceci est accompli avec !Ref
. De même, une référence est créée à l’équilibreur de charge.