In diesem Artikel möchte ich die Schritte für das Veröffentlichen einer statischen Webseite, zum Beispiel einer "Landing Page" mit Terraform und AWS zeigen.
Voraussetzung
Vorgehen
Folgende Schritte werden in der Terraform ausgeführt, damit eine statische Webseite auf AWS veröffentlicht werden kann.
- Erstellen eines Buckets mit der entsprechenden Ressource.
- Erstellen einer Webseiten Konfiguration für das Bucket.
- Erstellen eines Objektes im Bucket.
Bucket erstellen
Im ersten Schritt wird ein Bucket erstellt.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "eu-central-1"
access_key = "DEIN SCHLÜSSEL"
secret_key = "DEIN SCHLÜSSEL"
}
resource "aws_s3_bucket" "webapp" {
bucket = "schaedld-webapp"
object_lock_enabled = false
}
Die Befehle terraform init, terraform plan -out sampleplan, terraform apply sampleplan und terraform destroy (In Produktion eher vorsichtig damit umgehen) ausgeführt. Diese sind durchgängig durch das ganze Beispiel immer wieder anzuwenden.
Terraform init
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 3.0"...
- Installing hashicorp/aws v3.75.1...
- Installed hashicorp/aws v3.75.1 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
Terraform plan
terraform plan -out sampleplan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket.webapp will be created
+ resource "aws_s3_bucket" "webapp" {
+ acceleration_status = (known after apply)
+ acl = "private"
+ arn = (known after apply)
+ bucket = "schaedld-webapp"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ hosted_zone_id = (known after apply)
+ id = (known after apply)
+ object_lock_enabled = false
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags_all = (known after apply)
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
+ object_lock_configuration {
+ object_lock_enabled = (known after apply)
+ rule {
+ default_retention {
+ days = (known after apply)
+ mode = (known after apply)
+ years = (known after apply)
}
}
}
+ versioning {
+ enabled = (known after apply)
+ mfa_delete = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Saved the plan to: sampleplan
To perform exactly these actions, run the following command to apply:
terraform apply "sampleplan"
Terraform apply
terraform apply sampleplan
aws_s3_bucket.webapp: Creating...
aws_s3_bucket.webapp: Creation complete after 2s [id=schaedld-webapp]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
In AWS ist das Bucket erstellt worden.
Nun können die weiteren Elemente hinzugefügt werden.
Erstellen der Webseiten Konfiguration
Damit das Bucket auch als Webseite für die Auslieferung von statischem Inhalt funktioniert, muss eine Webseitenkonfigurationselement in Terraform hinzugefügt werden. (Aus Platzgründen habe ich die vorherigen Schritte weggelassen.)
resource "aws_s3_bucket_website_configuration" "webappcfg" {
bucket = aws_s3_bucket.webapp.bucket
index_document {
suffix = "index.html"
}
}
Wird nun terraform apply sampleplan ausgeführt, so ist zu sehen, dass 2 Ressourcen erstellt worden sind.
terraform apply sampleplan
aws_s3_bucket.webapp: Creating...
aws_s3_bucket.webapp: Creation complete after 1s [id=schaedld-webapp]
aws_s3_bucket_website_configuration.webappcfg: Creating...
aws_s3_bucket_website_configuration.webappcfg: Creation complete after 0s [id=schaedld-webapp]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Klickt man im Portal auf das Bucket Objekt, gelangt man in die Verwaltungsseite des Objektes.
Wählt man die Option Eigenschaften, so gelangt man in die Einstellungen des Buckets. Navigiert man ans untere Ende der Seite, ist folgender Punkt zu sehen:
Hier zu sehen, ist dass diese Option aktiviert ist. Wenn man nun den bereitgestellten Link anklickt, gelangt man auf eine Seite, die einem den Zugriff verwehrt, da noch kein Objekt für einen öffentlichen Lesezugriff vorhanden ist.
Nun kann mit dem nächsten Schritt, dem erstellen eines Objekts für das Bucket fortgefahren werden.
Nun kann mit dem nächsten Schritt, dem erstellen eines Objekts für das Bucket fortgefahren werden.
Erstellen eines Objektes im Bucket
Als letztes Puzzle-Teilchen, ist das Objekt für das Bucket hinzuzufügen. In diesem Beispiel ist es ein einfaches Index.html, dass als "Landing Page" verwendet werden könnte, wenn man frischer Besitzer einer Domain ist und gerade die Webseite aufbaut.
resource "aws_s3_bucket_object" "index" {
bucket = aws_s3_bucket.webapp.bucket
content_type = "text/html"
key = "index.html"
content = <<EOF
<a href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js">https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js</a>
<div class="container py-4">
<div class="p-5 mb-4 bg-light rounded-3">
<div class="container-fluid py-5">
<h1 class="display-5 fw-bold">Custom jumbotron</h1>
<p class="col-md-8 fs-4">Using a series of utilities, you can create this jumbotron, just like the one in previous versions of Bootstrap. Check out the examples below for how you can remix and restyle it to your liking.</p>
Example button
</div>
</div>
</div>
<footer class="pt-3 mt-4 text-muted border-top">
© 2021
</footer>
</div>
EOF
acl = "public-read"
}
In diesem Beispiel ist eine Webseite als Multiline Content von Terraform HEREDOC Strings drin, die erstellt wird.
Die Ausführung mit terraform apply zeigt dass eine dritte Ressource erstellt worden ist.
terraform apply sampleplan
aws_s3_bucket.webapp: Creating...
aws_s3_bucket.webapp: Creation complete after 2s [id=schaedld-webapp]
aws_s3_bucket_website_configuration.webappcfg: Creating...
aws_s3_bucket_object.index: Creating...
aws_s3_bucket_object.index: Creation complete after 0s [id=index.html]
aws_s3_bucket_website_configuration.webappcfg: Creation complete after 0s [id=schaedld-webapp]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Die Kontrolle im AWS Portal, des Buckets offenbar, dass diese Datei angelegt worden ist.
Wir der Link, in den Eigenschaften des Buckets unter "Hosten einer statischen Webseite" angeklickt so ist nicht mehr die Access Denied Meldung zu sehen, sondern die bereitgestellte Webseite.
Die komplette Terraform Konfiguration sieht dann wie folgt aus:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "eu-central-1"
access_key = "AKIAXEP7TRWQSFUAJI65"
secret_key = "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"
}
resource "aws_s3_bucket" "webapp" {
bucket = "schaedld-webapp"
object_lock_enabled = false
}
resource "aws_s3_bucket_website_configuration" "webappcfg" {
bucket = aws_s3_bucket.webapp.bucket
index_document {
suffix = "index.html"
}
}
resource "aws_s3_bucket_object" "index" {
bucket = aws_s3_bucket.webapp.bucket
content_type = "text/html"
key = "index.html"
content = <<EOT
<a href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js">https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js</a>
<div class="container py-4">
<div class="p-5 mb-4 bg-light rounded-3">
<div class="container-fluid py-5">
<h1 class="display-5 fw-bold">Willkommen</h1>
<p class="col-md-8 fs-4">Willkommen auf der Landing Page der Firma Software Sorglos.</p>
</div>
</div>
</div>
<footer class="pt-3 mt-4 text-muted border-top">
© 2021
</footer>
</div>
EOT
acl = "public-read"
}
Fazit
Mir nur wenig Aufwand, kann ein erster Kontaktpunkt zu einer neuen Firma auf AWS bereitgestellt werden. Dies ist nur ein Beispiel und hat noch keine Sicherheitsfunktionen aktiviert (vgl. Hosting a static Webseite using Amazon S3).