Créez une image Docker à l'aide de GitHub Action, enregistrez-la sur Amazon ECR et déployez-la sur Amazon ECS.
--Point
--Créer un ECR de destination --Créer un ECR pour déployer --Créez un utilisateur AWS IAM à utiliser avec GitHub Action (nécessite les autorisations ECR et ECS)
Continuez avec ceux-ci comme créés.
Créez un flux de travail comme celui ci-dessous et enregistrez-le dans .github / workflows /
dans le référentiel avec un nom approprié tel que deploy-to-ecs.yml
.
En poussant la balise vers la branche principale, ce flux de travail fonctionne, l'image Docker est poussée vers ECR et déployée vers ECS.
Opérez en utilisant la [Release] de Github (https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/managing-releases-in-a-repository) Je suppose que.
.github/workflows/deploy-to-ecs.yml
name: Deploy to ECS
on:
push:
tags:
- v*
env:
ECR_REPOSITORY: your-repository-name
ECS_SERVICE: your-service-name
ECS_CLUSTER: your-cluster-name
jobs:
deploy:
name: Deploy to ECS
if: github.event.base_ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Configure AWS Credentials #Paramètres d'autorisation d'accès AWS
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR #Processus de connexion ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Set Docker Tag Env #Faire correspondre la version de l'image Docker à la balise
run: echo "::IMAGE_TAG=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")" >> $GITHUB_ENV
- name: Build, tag, and push image to Amazon ECR #Construction d'image Docker&Push
env:
DOCKER_BUILDKIT: 1
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build --cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 -f Dockerfile -t $ECR_REPOSITORY .
docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
- name: Render Amazon ECS task definition for app container #Rendu du fichier de définition de tâche ECS du conteneur d'application
id: render-app-container
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: .aws/ecs/task-definition.json
container-name: app
image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
- name: Deploy to Amazon ECS service #Déploiement du service ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-app-container.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: false
Le fonctionnement du workflow sera expliqué concrètement dans l'ordre du haut.
name: Deploy to ECS
J'ai décidé du nom du workflow. Ce nom sera affiché lorsque vous vérifierez le flux de travail dans la liste à partir du référentiel Github ou de l'onglet Action. Lors de la création de plusieurs flux de travail dans un environnement de vérification ou un environnement de production, il est recommandé de modifier le nom afin qu'il soit facile à distinguer.
on:
push:
tags:
- v*
Cela fonctionne lorsque les balises commençant par v
telles que v1.0.0
sont poussées et Release On suppose que ce flux de travail fonctionnera en créant (/ github / administration-a-repository / manage-releases-in-a-repository).
Aussi, cette fois dans les travaux afin que cela ne fonctionne pas si la balise est poussée vers une autre branche
if: github.event.base_ref == 'refs/heads/main'
Cela ne fonctionne pas si ce n'est pas la branche principale comme.
Pour le faire fonctionner lorsqu'il est poussé vers une branche spécifique, omettez la description de if
on:
push:
branches:
- target-branch
Veuillez décrire comme. (Remplacez la branche cible par la branche à déployer.)
Afin de se rendre compte que cela fonctionne quand une balise est poussée vers une branche spécifique par la méthode de description de on: push:
on:
push:
tags:
- v*
branches:
- target-branch
Si vous écrivez comme, ce sera une condition ou (lorsque la balise ou la branche est poussée) au lieu de la condition et, alors spécifiez la balise cible avec on: push:
et cible avec if
La branche de est spécifiée.
env:
ECR_REPOSITORY: your-repository-name
ECS_SERVICE: your-service-name
ECS_CLUSTER: your-cluster-name
Il est affecté à une variable d'environnement pour réduire la description de la valeur qui est utilisée plusieurs fois dans le travail.
Veuillez changer votre-〇〇〇-nom
en celui de votre environnement
jobs:
deploy:
name: Deploy to ECS
if: github.event.base_ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
Vérifiez la branche cible dans l'environnement de ubuntu-latest
et commencez à exécuter le travail.
(Comme mentionné précédemment, la ligne if
est écrite de sorte qu'elle ne sera exécutée que dans la branche principale lorsque l'étiquette est poussée. Il n'est pas nécessaire si la condition de fonctionnement est modifiée de pousser dans la branche.)
- name: Configure AWS Credentials #Paramètres d'autorisation d'accès AWS
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
Je suis connecté au compte AWS qui a créé l'ECR à pousser et l'ECS à déployer.
Déployez à l'aide de Github's Secret (https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets) Accès IAM et clés secrètes AWS_ACCESS_KEY_ID Veuillez vous inscrire avec
et AWS_SECRET_ACCESS_KEY
.
- name: Login to Amazon ECR #Processus de connexion ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
Connectez-vous à ECR pour le compte AWS que vous avez connecté à l'étape 5.
- name: Set Docker Tag Env #Faire correspondre la version de l'image Docker à la balise
run: echo "::IMAGE_TAG=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g")" >> $GITHUB_ENV
La balise poussée pour que la balise image de Docker ait la même valeur que la balise de git est retirée dans un format comme v1.0.0
et affectée à la variable d'environnement.
Si vous n'utilisez pas de balises dans les conditions de fonctionnement du workflow,
run: echo "::IMAGE_TAG=${{ github.sha }}" >> $GITHUB_ENV
Je pense que c'est une bonne idée d'utiliser un hachage de validation pour rendre la balise d'image unique.
- name: Build, tag, and push image to Amazon ECR #Construction d'image Docker&Push
env:
DOCKER_BUILDKIT: 1
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build --cache-from=$ECR_REGISTRY/$ECR_REPOSITORY:latest --build-arg BUILDKIT_INLINE_CACHE=1 -f Dockerfile -t $ECR_REPOSITORY .
docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker tag $ECR_REPOSITORY:latest $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
Lors de la création d'une image Docker localement, la génération accélère à l'aide de l'image précédemment créée, mais GitHub Action ne conserve pas le résultat de la génération précédente, donc la génération prend du temps à chaque fois.
Par conséquent, ici, docker build --cache-from
de Docker est utilisé pour accélérer la construction.
Ce que nous faisons est de créer une image docker, en poussant la balise enregistrée dans la variable d'environnement IMAGE_TAG, et la valeur changera dynamiquement pour chaque opération de workflow, et la valeur au moment de la construction précédente sera utilisée. Comme il est difficile de l'obtenir, je pousse également la dernière balise et utilise la dernière balise pour la mise en cache. En faisant cela, le cache peut être utilisé tout en étant cohérent avec la balise release.
(DOCKER_BUILDKIT
, BUILDKIT_INLINE_CACHE
est décrit car il est nécessaire d'utiliser --cache-from
.)
Remarque: Si vous utilisez la génération en plusieurs étapes de Docker, vous ne pouvez pas mettre en cache cette méthode car l'image Docker n'inclut pas l'ensemble du processus de génération. Dans ce cas, je pense que vous devriez vous référer aux Articles comme celui-ci.
- name: Render Amazon ECS task definition for app container #Rendu du fichier de définition de tâche ECS du conteneur d'application
id: render-app-container
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: .aws/ecs/task-definition.json
container-name: app
image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
Pour exécuter ECS, une définition de tâche est requise et il est nécessaire de décrire le référentiel et les informations de balise de l'image Docker à utiliser. Par conséquent, lors de la mise à jour de DockerImage, il est également nécessaire de mettre à jour la définition de tâche, et ce processus est en cours d'exécution.
今回はレポジトリへタスク定義ファイル.aws/ecs/task-definition.json
を作成してあり、そのファイルを呼び出し、Dockerイメージの情報を更新しています。
Exemple de référence de task-definition.json
)
{
"containerDefinitions": [
"portMappings": [
{
"hostPort": 80,
"protocol": "tcp",
"containerPort": 80
}
],
"image": "your-image-name",
"name": "app"
}
],
"cpu": "256",
"executionRoleArn": "your-role-name",
"family": "your-family",
"memory": "512",
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc"
}
Lire depuis s3 semble être possible, alors veuillez gérer chaque définition de tâche que vous aimez.
- name: Deploy to Amazon ECS service #Déploiement du service ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-app-container.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: false
Il est déployé sur ECS en fonction de la définition de tâche créée dans 9.
En définissant wait-for-service-stabilite
sur true
, il est possible d'attendre la fin de l'exécution jusqu'à ce que le déploiement soit terminé et de notifier la fin du déploiement, mais le temps d'exécution des actions Github augmentera. Il est possible qu'il dépasse le cadre d'exécution.
Il est également possible de suspendre l'achèvement du déploiement à l'aide d'AWS Lambda et de le notifier, il est donc recommandé de le faire dans un environnement avec de nombreux déploiements.
Si le flux ci-dessus fonctionne correctement, le déploiement est terminé.
- name: Run Migrate #Lancer la migration
env:
CLUSTER_ARN: your_cluster_arn
ECS_SUBNER_FIRST: your_subnet_first
ECS_SUBNER_SECOND: your_subner_second
ECS_SECURITY_GROUP: your_security_group
run: |
aws ecs run-task --launch-type FARGATE --cluster $ECS_CLUSTER --task-definition ${{ steps.put-migrate-task.outputs.render-app-container }} --network-configuration "awsvpcConfiguration={subnets=[$ECS_SUBNER_FIRST, $ECS_SUBNER_SECOND],securityGroups=[$ECS_SECURITY_GROUP],assignPublicIp=ENABLED}" > run-task.log
TASK_ARN=$(jq -r '.tasks[0].taskArn' run-task.log)
aws ecs wait tasks-stopped --cluster $CLUSTER_ARN --tasks $TASK_ARN
Je voulais migrer la base de données avant de déployer cette fois, j'ai donc ajouté un tel travail à l'ECS à l'étape 10 avant de déployer et d'exécuter la tâche seule. En faisant cela, il est également possible d'exécuter une seule tâche dans Github Actions.
Lors du déploiement sur ECS, je pense qu'il existe des options telles que la combinaison d'AWS CodeBuild et d'AWS CodePipeline, mais il est également possible de déployer facilement à l'aide de GitHub Action.
J'ai beaucoup fait référence à l'article suivant.
Recommended Posts