Ce contenu a été mis à jour le 22/12/2021 pour pointer vers la version 2.5.5 de Traefik Proxy.
La gestion d'ECS n'est plus en beta, et il est possible d'exploiter un role au lieu d'une access key / secret key.
Le code Terraform disponible sur le repository GitLab a été mis à jour et testé avec la version 1.1.2 (Lien de la pull request)
Traefik est un reverse proxy que nous avons déjà évoqué sur ce blog par le passé. Très puissant couplé avec des containers, il permet une gestion fine et légère de son trafic.
Il y a quelques jours, Containous, l’éditeur de Traefik, a annoncé la sortie de Traefik 2.3.0-rc2. Cette nouvelle version apporte quelques changements, et notamment :
J'ai déjà abordé les deux premiers points sur mon blog personnel et je vais m'intéresser ici au support du backend ECS (Elastic Container Service) sur AWS via un nouveau provider Traefik.
A l’instar de Terraform, Traefik utilise une notion de provider pour définir les services sur lesquels il va se connecter.
Chaque provider a un vocabulaire et une configuration qui lui est propre. L’idée de base étant bien sûr d’avoir un noyau léger, Traefik, et de charger uniquement les providers que l’on utilise.
Il existe aujourd’hui une quinzaine de providers disponibles pour Traefik, comme par exemple Docker, Kubernetes, Rancher, Etcd, Consul etc…
Le provider est la source de données que Traefik va exploiter pour découvrir les backends auxquels il va se connecter.
Un peu de contexte : ECS est l’orchestrateur managé d’AWS, il permet de piloter des containers sur des EC2 ou sur un autre service, Fargate, qui permet d’exécuter ses containers en mode serverless.
Dans Fargate, on réserve simplement des ressources, et Amazon se charge de l’infrastructure sous-jacente pour nous (parce que le serverless ce n’est pas magique).
L’ajout du provider ECS permet donc à Traefik de découvrir dynamiquement des ressources pilotées par ECS, afin de les rattacher directement à lui même, ce qui donne plus de dynamisme dans vos déploiements. Cette découverte repose sur Traefik lui-même en utilisant du polling via les APIs d’AWS.
De plus, cela permet de ne plus avoir un AWS ALB par ressource, ou avec beaucoup de règles, mais d’en avoir simplement un qui renvoie vers Traefik, et c’est ce dernier qui s’occupe de tout le routage. De quoi interconnecter Traefik avec ECS peu importe où il est déployé. L’exemple ici réutilise ECS par simplicité, ce n’est pas indispensable, vous pouvez l’héberger où vous voulez.
Je vous propose donc un petit hands-on en exploitant ce provider, avec toutefois un petit disclaimer :
Le code complet du déploiement Terraform est disponible ici.
Je ne vais pas décrire ici l’ensemble du déploiement Terraform, car ce n’est pas le coeur de cet article, je vais plutôt m’attarder sur les points qui nous intéressent pour Traefik, et les nuances à prendre en compte.
La policy IAM, utilisée aussi en tant qu’utilisateur IAM dans l’exemple, en raison du bug décrit précédemment :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TraefikECSReadAccess",
"Effect": "Allow",
"Action": [
"ecs:ListClusters",
"ecs:DescribeClusters",
"ecs:ListTasks",
"ecs:DescribeTasks",
"ecs:DescribeContainerInstances",
"ecs:DescribeTaskDefinition",
"ec2:DescribeInstances"
],
"Resource": [
"*"
]
}
]
}
Comme on peut le noter, il s’agit de droits uniquement en lecture sur les services ECS et EC2, car ECS peut exploiter EC2 pour ses noeuds d’exécution.
A noter qu’il est tout à fait possible de restreindre cette policy, dans un modèle least privilege, comme préconisé par AWS, en réduisant par exemple le scope des ECS visibles par Traefik, ou en autorisant uniquement les EC2 qui porteraient un tag spécifique.
La policy indiquée ici est tirée de la documentation officielle.
La taskdefinition de Traefik est assez simple :
[
{
"name": "traefik",
"image": "traefik:v2.5.5",
"entryPoint": ["traefik", "--providers.ecs.clusters", "${ecs_cluster_name}", "--log.level", "DEBUG", "--providers.ecs.region", "${region}", "--api.insecure"],
"essential": true,
"logConfiguration":{
"logDriver": "awslogs",
"options": {
"awslogs-group": "${loggroup}",
"awslogs-region": "${region}",
"awslogs-stream-prefix": "traefik"
}
},
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
},
{
"containerPort": 8080,
"hostPort": 8080
}
]
}
]
L’information importante ici est bien entendu l’entrypoint. L’entrypoint est la commande qui sera exécutée par ECS au lancement du container.
Quand on regarde les paramètres de la ligne de commande nous voyons donc :
J’ai choisi de faire la configuration via la ligne de commande, mais il est tout à fait possible de faire cette dernière via les fichiers de configurations de Traefik, pour plus d’informations à ce sujet, je vous invite à regarder la documentation officielle.
La taskdefinition de Whoami, le backend est prévu pour exposer les informations utilisée par Traefik :
[
{
"name": "whoami",
"image": "containous/whoami:v1.5.0",
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
],
"dockerLabels":
{
"traefik.http.routers.whoami.rule": "Host(`${alb_endpoint}`)",
"traefik.enable": "true"
}
}
]
Whoami est une image minimaliste, créée par Containous à des fins de démonstration. Elle ne nécessite pas de paramètres particuliers.
On peut voir que j’ajoute deux paramètres, via des labels Docker sur mon container :
Il est maintenant possible de déployer le code Terraform, qui va nous mettre en place notre cluster ECS, nos containers, la gestion de l’IAM et un load balancer frontal.
Au bout de quelques minutes, notre serveur Traefik est maintenant disponible.
Vous pouvez accéder au tableau de bord de Traefik via l’url de votre load balancer (renvoyée par Terraform), sur le port 8080.
En allant voir dans les services, vous voyez normalement un service whoami, qui correspond à notre déploiement.
Comme vous pouvez le voir sur la capture d’écran ci dessous :
Un accès à l’url du load balancer nous renvoie le container whoami, en rafraîchissant la page, vous devriez voir l’IP changer, ce qui signifie bien que nous avons du load balancing sur notre service.
Traefik ajoute une nouvelle corde à son arc en permettant la découverte native de services déployés dans ECS.
Actuellement, on peut sentir que le vernis n’est pas encore sec, de part le bug que j’ai remonté, mais aussi le fait que la documentation manque de clarté sur certains aspects. Ainsi, je ne vous recommande pas d’utiliser cette fonctionnalité dans son état actuel sur un environnement de production, encore une fois il s’agit d’une release candidate, on préférera attendre la version stable pour cet usage.
Néanmoins, ce produit de la french tech nous prouve une fois de plus qu’il est capable d’évoluer et de s’adapter aux besoins de ses utilisateurs. Aucun doute sur le fait qu’ECS sera bientôt un provider parmis les autres pour Traefik.