Deployment einer Antora-Site in AWS mit CI/CD und Jenkins
Juli 5, 2022
--
Deploying an Antora Site in AWS 1200x628

Deployment einer Antora-Site in AWS mit CI/CD und Jenkins

Dies ist der zweite von zwei Artikeln darüber, wie man effizient Dokumentations-Sites mit Antora erstellt und einsetzt. Im ersten Artikel "Using AsciiDoc and Antora to Create Online Technical Documentation" haben wir Ihnen gezeigt, wie Antora den Prozess der Erstellung von qualitativ hochwertigem Single-Source-Content unter Verwendung der AsciiDoc-Markup-Sprache erleichtern kann.

In diesem Artikel zeigen wir Ihnen, wie Sie die Website effizient und sicher auf AWS bereitstellen und veröffentlichen können. Außerdem beschreiben wir die Infrastruktur und die Bereitstellungspipeline mithilfe von Terraform und Jenkins, zwei beliebten Plattformen für die Infrastrukturorchestrierung und die Erklärung der kontinuierlichen Bereitstellungspipeline.

Am Ende werden wir den Quellcode für die Dokumentation, die Infrastruktur und die kontinuierliche Bereitstellungspipeline, auch bekannt als "Alles-als-Code", in unseren Git-Repositories haben. Jede Änderung an den Inhalten oder der Infrastruktur wird dann automatisch auf die Umgebungen der Website angewendet.

AWS-Infrastruktur

Das folgende Diagramm zeigt die AWS-Ressourcen und ihre Verbindungen für das Hosting und die Bereitstellung von Antora-Ressourceninhalten von AWS für Endbenutzer. In den folgenden Abschnitten gehen wir auf jede Ressource ein.

AWS_infra_diagram_Antora

Hosting von Inhalten und Assets in S3

Zuallererst müssen wir unsere Dokumentationsinhalte und statischen Assets wie Bilder, JavaScript, CSS und Videos in einem sicheren und skalierbaren Speicher ablegen. Amazon S3 wurde entwickelt, um eine beliebige Anzahl von Dateien auf einfache Weise dauerhaft, hochverfügbar und skalierbar zu niedrigen Kosten zu speichern und abzurufen.

Nachfolgend sehen Sie die Terraform-Konfiguration für den S3-Bucket:

Bash
  resource "aws_s3_bucket" "bucket" { bucket = var.site_domain acl = "private" } resource "aws_s3_bucket_public_access_block" "public_access_block" { bucket = aws_s3_bucket.bucket.id block_public_acls = true block_public_policy = true restrict_public_buckets = true ignore_public_acls = true } resource "aws_s3_bucket_policy" "bucket_policy" { bucket = aws_s3_bucket.bucket.id policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Sid": "OAIReadGetObject", "Effect": "Allow", "Principal": { "AWS": "${aws_cloudfront_origin_access_identity.identity.iam_arn}" }, "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::${var.site_domain}/*", "arn:aws:s3:::${var.site_domain}" ] } ] } POLICY depends_on = [aws_s3_bucket_public_access_block.public_access_block] }  

Normalerweise benennen wir den Bucket genauso wie die Variable site_domain, zum Beispiel documentation.yourdomain.com. Dadurch wird die Einzigartigkeit des Buckets global sichergestellt.

Der direkte öffentliche Zugriff auf den Bucket ist in der Ressource aws_s3_bucket_public_access_block deaktiviert, da wir den Zugriff auf den Bucket-Inhalt nur über CloudFront unter Verwendung der Origin Access Identity (OAI) erlauben, indem wir das Bucket-Richtliniendokument aws_cloudfront_origin_access_identity.identity.iam_arn als Principal angeben.

Tipps zum Schreiben von Antora-Makros

Wir verwenden AsciiDoc und Antora, um die Dokumentation von Magnolia zu erstellen. Um dynamische Inhalte wie Versionsnummern zu den statischen Seiten hinzuzufügen, haben wir Antora-Makros erstellt. Lesen Sie unseren Blog, um mehr zu erfahren.

Bereitstellung von Inhalten über CloudFront

S3 unterstützt das Hosten statischer Websites direkt im Bucket, aber es ist die beste Praxis, eine CloudFront-Verteilung vor Ihrem S3-Bucket zu verwenden, um Ihre Inhalte effizient an die Benutzer zu liefern.

CloudFront ist ein Content Delivery Network (CDN), das Inhalte über ein weltweites Netzwerk von Rechenzentren, den sogenannten Edge-Standorten, bereitstellt. Durch die Zwischenspeicherung von Inhalten und die Weiterleitung von Anfragen an nahegelegene Edge-Standorte reduziert CloudFront die Belastung des S3-Buckets und sorgt so für schnellere Reaktionszeiten. Außerdem ist die Bereitstellung von Inhalten über CloudFront kostengünstiger als die Bereitstellung von Dateien direkt von S3, da für die Übertragung von Daten von S3 zu CloudFront keine Gebühren anfallen.

In der CloudFront-Distribution geben wir den S3-Bucket als Ursprung mit seiner spezifischen Ursprungs-ID und dem regionsspezifischen Domainnamen an.

Im vorigen Abschnitt haben wir den S3-Bucket so konfiguriert, dass der öffentliche Zugriff gesperrt ist. Wir erteilen der Origin Access Identity (OAI), die wir für die CloudFront-Distribution in ihrer Origin-Konfiguration erstellen, Lese- und Abrufrechte. Weitere Informationen zur OAI-Konfiguration finden Sie in der AWS-Dokumentation"Restricting access by using an origin access identity (OAI)".

Jetzt können Sie die Cache-Verhalten Einstellungen für die Distribution und ihren Ursprung festlegen, einschließlich der Caching-Funktionalität auf der Grundlage von Pfadmustern, HTTP-Methoden, HTTP-Headern und minimaler/maximaler TTL. Weitere Informationen finden Sie unter "Cache-Verhaltenseinstellungen".

Nachfolgend finden Sie die Terraform-Konfiguration für die OAI- und CloudFront-Verteilungsressourcen:

Bash
  resource "aws_cloudfront_origin_access_identity" "identity" { comment = "Origin access identity for docu web in S3" } locals { s3_origin_id = "${var.site_domain}-s3-origin" } resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = aws_s3_bucket.bucket.bucket_regional_domain_name origin_id = local.s3_origin_id s3_origin_config { origin_access_identity = aws_cloudfront_origin_access_identity.identity.cloudfront_access_identity_path } enabled = true is_ipv6_enabled = true comment = "Some comment" default_root_object = "index.html" aliases = [var.site_domain] price_class = "PriceClass_100" default_cache_behavior { allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] cached_methods = ["GET", "HEAD"] target_origin_id = local.s3_origin_id forwarded_values { query_string = false cookies { forward = "none" } } viewer_protocol_policy = "allow-all" min_ttl = 0 default_ttl = 3600 max_ttl = 86400 } restrictions { geo_restriction { restriction_type = "none" } } viewer_certificate { acm_certificate_arn = data.aws_acm_certificate.cert.arn ssl_support_method = "sni-only" minimum_protocol_version = "TLSv1.2_2018" } }  

Beachten Sie, dass wir im Block aws_cloudfront_distribution ein TLS-Zertifikat konfiguriert haben, das wir im nächsten Abschnitt beschreiben werden.

AWS-Zertifikatsverwaltung (ACM)

Die CloudFront-Distribution stellt die Inhalte nicht nur mit Caching und sicherem Zugriff auf den S3-Bucket über OAI bereit, sondern verbindet sich auch mit AWS ACM-Zertifikaten, um HTTPS mit Ihrer benutzerdefinierten Domain zu erreichen. In der folgenden Konfiguration wird davon ausgegangen, dass das Zertifikat bereits in ACM ausgestellt und in der Domain-Variablen ssl_cert_domain gespeichert ist.

Der ARN des Zertifikats wird dann im Block viewer_certiticate der aws_cloudfront_distribution konfiguriert.

Bash
  data "aws_acm_certificate" "cert" { domain = var.ssl_cert_domain statuses = ["ISSUED"] provider = aws.us-east-1 } resource "aws_cloudfront_distribution" "s3_distribution" { ... viewer_certificate { acm_certificate_arn = data.aws_acm_certificate.cert.arn ssl_support_method = "sni-only" minimum_protocol_version = "TLSv1.2_2018" } }  

Route53 als DNS-Dienst

Als letzten Teil des Stacks konfigurieren wir einen Amazon Route 53-Eintrag für die DNS-Auflösung. In diesem Schritt wird die Domain unserer Website mit der CloudFront-Distribution verknüpft, sofern wir bereits eine gehostete Zone (route53_hosted_zone) in Route 53 konfiguriert haben.

Bash
  data "aws_route53_zone" "r53_zone" { name = var.route53_hosted_zone } resource "aws_route53_record" "r53_records" { name = var.site_domain type = "A" alias { evaluate_target_health = false name = aws_cloudfront_distribution.s3_distribution.domain_name zone_id = aws_cloudfront_distribution.s3_distribution.hosted_zone_id } zone_id = data.aws_route53_zone.r53_zone.zone_id }  

Integration in die CI/CD-Pipeline

Wenn Sie die Schritte aus dem ersten Artikel bis hierher befolgt haben, haben Sie Ihre Inhalte und Infrastruktur in Code beschrieben. Jetzt können wir mit Terraform beginnen, um die Infrastruktur zu erstellen, dann den Inhalt der Website mit Antora erstellen und alle Inhalte und Assets in den S3-Bucket schieben.

Im Allgemeinen ist es eine gute Idee, eine automatisierte Bereitstellungspipeline mit allen oben genannten Schritten zu erstellen, um eine nahtlose Bereitstellung zu gewährleisten. Alle Änderungen aus dem Content-Repository der Site oder dem Infrastruktur-Repository sollten überprüft, erstellt und in der bereitgestellten Site berücksichtigt werden.

Nachfolgend sehen Sie ein Beispiel für die Jenkins-Pipeline zur Bereitstellung der Antora-Site in zwei Umgebungen: Staging und Produktion.

Jenkins_pipeline_stage_view_Antora

Wenn Sie es wünschen, können Sie den Produktionseinsatz auch über einen Parameter optional machen.

Dies sind die Schritte in der Pipeline:

Überprüfen von Änderungen

In diesem Schritt führen wir eine erste Überprüfung des Quellcodes durch. Im Moment gibt es kein "Linting" für Antora, aber wir können terraform plan verwenden, um den Plan der Änderungen in der Infrastruktur zu überprüfen und zu generieren.

UI-Bündel erstellen

Dieser Schritt bezieht sich auf den Abschnitt "Erstellen des Antora-Demo-UI-Projekts" aus dem vorherigen Artikel. Er wird typischerweise mit einem Gulp-Build-Skript durchgeführt, zum Beispiel:

Bash
  cd ui/ npm install npm install gulp-cli ./node_modules/.bin/gulp bundle  

Antora-Website erstellen

Dieser Schritt bezieht sich auf den Abschnitt "Ausführen des Antora-Demo-Playbooks" aus dem vorherigen Artikel, um die HTML-Seiten aus dem Playbook zu generieren:

Bash
  # generierte Dateien im Verzeichnis build/site/ antora generate playbook.yml  

Bereitstellung von Infra in Staging/Produktion

Um die Infrastrukturressourcen in AWS zu erstellen, führen wir zum Beispiel terraform apply für jede Umgebung aus:

Bash
  # apply in staging terraform apply -var-file=docu.staging.tfvars -auto-approve # apply in production terraform apply -var-file=docu.prod.tfvars -auto-approve  

Bereitstellen der Antora-Site auf S3 in Staging/Production

Im letzten Schritt werden alle Website-Inhalte und Assets mit dem Befehl sync aus dem AWS CLI-Tool in den S3-Bucket übertragen. Beachten Sie, dass die Option --delete verwendet wird, um sicherzustellen, dass sich keine veralteten Dateien im S3-Bucket befinden.

Bash
  # aws s3 sync build/site/ s3://${env.STAGING_S3_BUCKET}/ --delete # deploy in production aws s3 sync build/site/ s3://${env.PRODUCTION_S3_BUCKET}/ --delete  

Wir haben in diesem Beispiel Jenkins verwendet, aber die Pipeline sollte bei anderen CI/CD-Plattformen ziemlich ähnlich sein.

Moderne Dokumentationsprojekte

Jede Änderung am Antora-Dokumentationsprojekt wird dank der Entwicklungspipelines, die sich um die Erstellung und Bereitstellung kümmern, automatisch bereitgestellt. Dieser Prozess beschleunigt den iterativen Ansatz für eine moderne Dokumentation, die sonst hinter der Entwicklung zurückbleiben würde, erheblich.

Die Bereitstellung der Antora-Website über das CDN trägt auch dazu bei, die negativen Auswirkungen der geografischen Lage des Kunden zu mildern.

Alles in allem hält dieser Ansatz die Infrastrukturkosten niedrig und macht moderne Dokumentationsprojekte leistungsfähiger und robuster.

Über den autor

Khiem Do Hoang

Senior Site Reliability Engineer, Magnolia

Khiem works on Magnolia’s Site Reliability Engineering (SRE) team. As an SRE he helps to ensure that Magnolia deploys smoothly and reliably on cloud infrastructure. He is involved in the design and implementation of automation processes, CI/CD, Infrastructure as Code (IaC), monitoring, and logging. Khiem is also interested in designing systems to take advantage of the automation and scalability of cloud-native, microservice-oriented, and containerized environments using technology such as Docker and Kubernetes.