[PYTHON] CodeCommit + CodePipeline mit CDK

Einführung

In diesem Beitrag wird der Mechanismus zum Hochladen von Dateien in S3 mit CodeCommit + CodePipeline vorgestellt, mit dem ich während des Studiums von AWS CDK versucht habe, einen Prototyp zu erstellen. Im Ingenieurteam gab es eine Stimme, die sagte "Ich möchte es berühren", und ich war daran interessiert, aber ich hörte einen Ruf von Ingenieuren in einer anderen Abteilung, der sagte "CDK ist gut", also berührte ich es.

Was ist AWS CDK?

Was ist AWS CDK? `Das AWS Cloud Development Kit (AWS CDK) modelliert und stellt Cloud-Anwendungsressourcen unter Verwendung vertrauter Programmiersprachen bereit. Es ist ein Open-Source-Softwareentwicklungsframework dafür. Es ist praktisch, die Infrastruktur mit Python oder TypeScript zu definieren.

Hintergrund

Der Frühste

In der Vergangenheit wurde Cloud 9 als Produktionsumgebung verwendet, aber die Auswahlanforderungen zu diesem Zeitpunkt sind

  1. Kann gleichzeitig bearbeitet werden
  2. Sie können eine Vorschau der Artefakte anzeigen
  3. Die Grundzertifizierung ist in der Vorschau enthalten
  4. Versionskontrolle ist möglich

Also habe ich eine Sache gemacht, dass HTML-Dateien und Bilddateien von Cloud9 über CodeCommit mit Cloud9 + Codecommit + Lambda + CloudFront + Lambda @ edge + S3 von S3 auf S3 hochgeladen und über CloudFront in der Vorschau angezeigt werden können. Zuerst schien es sich gut zu drehen.

Problem

Cloud9, das anfangs gut zu funktionieren schien, wurde allmählich problematisch.

  1. Einige Dateien werden nicht in S3 hochgeladen. (Dies ist verdächtig, dass CodeCommit → S3 von Lambda ausgeführt wird.)
  2. Die Anzahl der Projekte nimmt zu und die Kapazität von Cloud9 wird eingeschränkt (weil es ein Produkt von Image Morimori ist ...)
  3. Es gibt ein Zeichen dafür, dass die Simultanbearbeitungsfunktion überhaupt nicht verwendet wird ...

Cloud9 war also nicht erforderlich. Wenn ja, hat sich die Dynamik für das Remaking erhöht, indem gesagt wurde, dass es besser wäre, es lokal zu machen und auf S3 aufzusteigen. (Da die Mitglieder, die tatsächlich codieren, nicht die Personen sind, die AWS berühren, wollte ich auch ein Formular bereitstellen, das AWS nicht so direkt wie möglich direkt gegenübersteht.)

Hauptthema

Für das Remake haben wir das CDK übernommen, von dem wir Gerüchte im Unternehmen gehört haben. CDK ist für die Ressourcenerstellung für CodeCommit, CodePipeline und CodeBuild auf der linken Seite der folgenden Abbildung verantwortlich. (S3 + CloudFront + Lambda @ edge ist dieselbe wie die vorherige.)

codecommit_diagram.png

In der Cloud9-Ära wurde "1Cloud9 (1EC2-Instanz) = mehrere Materie = 1 Repository" in "1 Materie = 1 Repository" geändert. Mit cd k deploy zu Beginn des Projekts wird das Repository erstellt und CodePipeline in CodeCommit vorbereitet. Jedes Mal, wenn Sie auf Master drücken, wird die Datei von CodeBuild in S3 hochgeladen.

Implementierung

Laut Dokumentation

$ npm install -g aws-cdk
$ mkdir test
$ cd test
$ cdk init test --language python
$ source .env/bin/activate
$ pip install -r requirements.txt

Beginnen Sie als.

app.py


#!/usr/bin/env python3
import os
from os.path import join, dirname
from dotenv import load_dotenv

from aws_cdk import core
from test.test_stack import TestStack


dotenv_path = join(dirname(__file__), '.env_file')
load_dotenv(dotenv_path)


app = core.App()
TestStack(app,
          "test",
          repo_name=os.environ["REPOSITORY_NAME"],
          env={"account": "xxxxxxxxxxxx", "region": "ap-northeast-1"})
app.synth()

test_stack.py


from aws_cdk import core
from aws_cdk import aws_codecommit as codecommit
from aws_cdk import aws_codebuild as codebuild
from aws_cdk import aws_codepipeline as codepipeline
from aws_cdk import aws_codepipeline_actions as codepipeline_actions
from aws_cdk import aws_iam as iam

class TestStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, repo_name: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        #Bucket-Name des Ausgabeziels
        s3_bucket_name = "test-bucket"
    
        #Erstellen eines CodeCommit-Repositorys
        repo = codecommit.Repository(self,
                                     "Repository",
                                     repository_name=repo_name,
                                     description="test.")
        repository = codecommit.Repository.from_repository_arn(self, repo_name, repo.repository_arn)

        #Definition der Code-Pipeline
        pipeline = codepipeline.Pipeline(self,
                                         id=f"test-pipeline-{repo_name}",
                                         pipeline_name=f"test-pipeline-{repo_name}")
        source_output = codepipeline.Artifact('source_output')

        #CodeCommit hinzufügen
        source_action =  codepipeline_actions.CodeCommitSourceAction(repository=repository,
                                                                     branch='master',
                                                                     action_name='source_collect_action_from_codecommit',
                                                                     output=source_output,
                                                                     trigger=codepipeline_actions.CodeCommitTrigger.EVENTS)
        pipeline.add_stage(stage_name='Source', actions=[source_action])

        #CodeBuild hinzufügen
        cdk_build = codebuild.PipelineProject(self,
                                              "CdkBuild",
                                              build_spec=codebuild.BuildSpec.from_object(dict(
                                                  version="0.2",
                                                  phases=dict(
                                                      build=dict(
                                                          commands=[f"aws s3 sync ./ s3://{s3_bucket_name}/"]
                                                      )
                                                  )
                                              )))
        cdk_build.add_to_role_policy(
            iam.PolicyStatement(
                resources=[f'arn:aws:s3:::{s3_bucket_name}', f'arn:aws:s3:::{s3_bucket_name}/*'],
                actions=['s3:*']
            )
        )

        build_output = codepipeline.Artifact("CdkBuildOutput")

        build_action = codepipeline_actions.CodeBuildAction(
                            action_name="CDK_Build",
                            project=cdk_build,
                            input=source_output,
                            outputs=[build_output])

        pipeline.add_stage(
            stage_name="Build",
            actions=[build_action]
        )

CodeBuild Wenn ich jetzt darüber nachdenke, denke ich, dass CodeDeploy gut für CodeBuild war, das nur "s3-Synchronisierung" ist. Ich möchte die Hierarchie auf der s3-Bucket-Seite einen Schritt tiefer machen, wenn ich "s3-Synchronisierung" mache, aber gibt es eine gute Lösung ...

Codebuild-Teil


#CodeBuild hinzufügen
cdk_build = codebuild.PipelineProject(self,
                                      "CdkBuild",
                                      build_spec=codebuild.BuildSpec.from_object(dict(
                                        version="0.2",
                                        phases=dict(
                                        build=dict(commands=[f"aws s3 sync ./ s3://{s3_bucket_name}/"])
                                      ))))

Bereitstellen

später

$ cdk deploy

Sie können es auf diese Weise bereitstellen, aber ich habe ein Skript wie folgt für den Benutzer erstellt.

make.sh


#!/bin/bash

if [ $# -ne 1 ]; then
  echo "Für die Ausführung ist ein Argument erforderlich." 1>&2
  echo "Geben Sie den Projektcode im Argument an. (Teilweise für die URL zum Zeitpunkt der Vorschau verwendet)"
  exit 1
fi
echo REPOSITORY_NAME=$1 > .env_file
cdk deploy test --profile xxxxxxx
#verpflichten
git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/$1 ../$1
mkdir ../$1/$1
touch ../$1/$1/.gitkeep
cd ../$1
git checkout -b master
git add -A
git commit -m "initial commit"
git push origin master

Nehmen Sie nun den Namen des Repositorys, das Sie erstellen möchten, als Argument

$ ./make.sh test_repository

Wenn ja, ist es OK.

Besorgnis, Sorge

Schließlich

Dieses Mal habe ich einen Mechanismus zum Hochladen von Dateien von CodeCommit nach S3 über CodeBuild mithilfe von CDK erstellt. Es scheint einen besseren Ruf zu haben als in der Cloud9-Ära, daher warte ich auf Feedback, während ich denke, dass es schön wäre, wenn Sie es so verwenden könnten, wie es ist. Ich denke, das CDK selbst ist gut, weil Sie CloudFormation nicht direkt bekämpfen müssen.

Recommended Posts

CodeCommit + CodePipeline mit CDK
[AWS] ECR mit AWS CDK erstellen
Erstellen eines AWS Fargate-Dienstes mit AWS CDK