AWS Grundlagen: Regionen, IAM und Hauptdienste

1. Übersicht

Dieser Artikel hilft dir, die drei wichtigsten Säulen schnell zu verstehen, wenn du neu mit AWS anfängst: Region (wo soll die Infrastruktur stehen), IAM (wer darf was) und die Hauptdienste (EC2, S3, RDS, Lambda, VPC…). Nach dem Lesen wirst du verstehen, wie man ein AWS-Konto sicher organisiert, wie man IAM Roles für Anwendungen erstellt, und du kannst Java-Code schreiben, der S3 über AWS SDK v2 aufruft.

2. Region und Availability Zone

AWS unterteilt die Infrastruktur in Regionen (geografische Bereiche, z. B. ap-southeast-1 in Singapur) und jede Region hat mehrere Availability Zones (AZ) — unabhängige Rechenzentren mit eigenständiger Stromversorgung und Netzwerk, die nah beieinander liegen, um niedrige Latenz zu erreichen, aber trotzdem isoliert sind für Fehlertoleranz (Fault Isolation).

aws ec2 describe-availability-zones --region ap-southeast-1

Der Befehl oben listet die AZs in der Region Singapur auf. Die Ausgabe sieht üblicherweise so aus:

ZoneName: ap-southeast-1a
ZoneName: ap-southeast-1b
ZoneName: ap-southeast-1c

Beim Systemdesign solltest du mindestens 2 AZs verwenden, um Ausfallsicherheit zu erreichen (High Availability). Eine Auto Scaling Group oder eine RDS Multi-AZ Instanz basieren beide auf diesem Prinzip.

Hinweis: Einige Dienste sind global (nicht an eine bestimmte Region gebunden) wie IAM, Route 53, CloudFront. Die meisten anderen Dienste (EC2, S3, RDS…) sind regional, Daten replizieren sich nicht automatisch zu anderen Regionen, es sei denn, du konfigurierst das explizit.

2.1. Wie man eine Region wählt

Drei Hauptkriterien: Latenz (nah bei den Benutzern), Compliance (Anforderungen, dass Daten im Land bleiben), und Kosten (Servicepreise unterscheiden sich zwischen Regionen). Für Benutzer in Vietnam ist ap-southeast-1 (Singapur) normalerweise die Standardwahl wegen niedriger Latenz und vollständiger Serviceverfügbarkeit.

3. IAM: User, Group, Role, Policy

IAM (Identity and Access Management) kontrolliert, wer auf welche Ressourcen zugreifen darf. Vier Kernkonzepte:

  • User: eine spezifische Identität (Person oder Service) mit eigenen Zugangsdaten.
  • Group: eine Sammlung von Usern, mit gemeinsamen Policies für einfachere Verwaltung.
  • Role: eine Menge von Berechtigungen ohne feste Zugangsdaten — verwendet für EC2, Lambda oder Cross-Account-Zugriff.
  • Policy: ein JSON-Dokument, das Berechtigungen (allow/deny) für Aktionen und Ressourcen beschreibt.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::order-invoices-bucket/*"
    }
  ]
}

Diese Policy erlaubt das Lesen und Schreiben von Objekten im Bucket order-invoices-bucket. Befestige diese Policy an eine Role und attach die Role an eine EC2 Instanz oder Lambda Funktion, die den Service InvoiceStorageService ausführt — die Anwendung hat dann automatisch die Berechtigung ohne hart codierte Access Key/Secret Key.

aws iam create-role \
  --role-name InvoiceServiceRole \
  --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy \
  --role-name InvoiceServiceRole \
  --policy-arn arn:aws:iam::123456789012:policy/InvoiceBucketAccess

Der erste Befehl erstellt eine Role mit trust-policy.json, das festlegt, wer diese Role “annehmen” darf (z. B. der EC2 Service). Der zweite Befehl befestigt eine spezifische Berechtigungspolicy an die Role.

Hinweis: Niemals Access Key/Secret Key direkt in den Code einbetten oder in Git commitzen. Verwende IAM Role (für Ressourcen, die auf AWS laufen) oder IAM Identity Center/SSO (für Benutzer).

3.1. Das Prinzip der geringsten Berechtigung

Gewähre nur die notwendigen Berechtigungen, verwende nicht AdministratorAccess für Service-Konten. Beispiel: wenn eine Lambda nur einen Bucket lesen muss, sollte sie nicht s3:* auf dem ganzen Konto bekommen.

{
  "Effect": "Deny",
  "Action": "s3:DeleteBucket",
  "Resource": "*"
}

Ein Deny Statement hat immer Vorrang vor Allow bei Konflikten — das ist eine Möglichkeit, ein “Sicherheitsnetz” gegen versehentliches Löschen wichtiger Buckets zu bauen.

4. Hauptdienste

4.1. Compute

  • EC2: virtuelle Maschinen, vermietet nach Stunden/Sekunden, du verwaltest das Betriebssystem.
  • Lambda: Code basierend auf Ereignisse ausführen (Event-Driven), keine Serververwaltung, Abrechnung nach Anzahl der Aufrufe und Ausführungszeit.
  • ECS/EKS: Container (Docker) mit Orchestrierung ausführen.
aws lambda invoke \
  --function-name CalculateOrderTotal \
  --payload '{"orderId":"ORD-1001"}' \
  response.json

Dieser Befehl ruft die Funktion CalculateOrderTotal mit JSON-Payload auf, das Ergebnis wird in response.json geschrieben.

4.2. Storage

  • S3: Object Storage, speichert beliebige Dateien (Bilder, Logs, Backups), mit 99.999999999% Haltbarkeit.
  • EBS: Block Storage angebunden an EC2.
  • EFS: gemeinsames Dateisystem, das von mehreren EC2 Instanzen gemountet werden kann.

4.3. Datenbank

  • RDS: verwaltete relationale Datenbank (MySQL, PostgreSQL…), automatische Backups, Patching.
  • DynamoDB: NoSQL, horizontale Skalierung automatisch, einstellige Millisekunden Latenz.

4.4. Netzwerk

  • VPC: privates virtuelles Netzwerk, du definierst Subnetze, Route Tables, Security Groups.
  • Security Group: Stateful-Firewall auf Instanzebene.
Resources:
  OrderServiceSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTPS inbound
      VpcId: vpc-0123456789abcdef0
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0

Dieser CloudFormation-Code erstellt eine Security Group namens OrderServiceSG, die nur Port 443 (HTTPS) für alle IPs öffnet — alle anderen Inbound-Regeln sind standardmäßig deny.

5. S3 von einer Java-Anwendung aufrufen

Dieser Abschnitt zeigt, wie ein Spring Boot Service Dateien zu S3 mit AWS SDK for Java v2 hochlädt.

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>s3</artifactId>
    <version>2.25.16</version>
</dependency>
public class InvoiceStorageService {

    private final S3Client s3Client;
    private final String bucketName;

    public InvoiceStorageService(S3Client s3Client, String bucketName) {
        this.s3Client = s3Client;
        this.bucketName = bucketName;
    }

    public void uploadInvoice(String orderId, byte[] content) {
        PutObjectRequest request = PutObjectRequest.builder()
                .bucket(bucketName)
                .key("invoices/" + orderId + ".pdf")
                .build();

        s3Client.putObject(request, RequestBody.fromBytes(content));
    }
}

S3Client wird über Constructor injiziert (Zugangsdaten werden automatisch von IAM Role geholt, wenn auf EC2/Lambda ausgeführt, kein Hard-Coding nötig). Die Methode uploadInvoice erstellt einen PutObjectRequest mit key als Objektpfad im Bucket, dann ruft putObject auf, um den Inhalt zu S3 zu pushen.

Bean-Konfiguration für S3Client:

@Bean
public S3Client s3Client() {
    return S3Client.builder()
            .region(Region.AP_SOUTHEAST_1)
            .build();
}

Keine explizite credentialsProvider nötig — das SDK nutzt die Default Credentials Provider Chain: sucht nacheinander nach Umgebungsvariablen, ~/.aws/credentials Datei, dann die IAM Role, die an EC2/ECS/Lambda gebunden ist.

5.1. Test mit Mock S3Client

@Test
void shouldCallPutObjectWithCorrectKey() {
    S3Client mockS3 = mock(S3Client.class);
    InvoiceStorageService service = new InvoiceStorageService(mockS3, "order-invoices-bucket");

    service.uploadInvoice("ORD-1001", "Rechnungsinhalt".getBytes());

    ArgumentCaptor<PutObjectRequest> captor = ArgumentCaptor.forClass(PutObjectRequest.class);
    verify(mockS3).putObject(captor.capture(), any(RequestBody.class));

    assertThat(captor.getValue().bucket()).isEqualTo("order-invoices-bucket");
    assertThat(captor.getValue().key()).isEqualTo("invoices/ORD-1001.pdf");
}

Der Test mockt S3Client (mit Mockito), um AWS nicht wirklich beim CI-Lauf aufzurufen. ArgumentCaptor fängt den tatsächlich gesendeten PutObjectRequest, dann prüft AssertJ mit bucket und key — sichert, dass die Request-Buildlogik korrekt ist ohne Netzwerkkosten.

Hinweis: Für echte Integrationstests mit S3 verwende LocalStack oder Testcontainers statt echte S3 Buckets aufzurufen — vermeidet Kosten und Datensicherheitsrisiken.

6. Häufige Fehler

  • S3 Bucket aus Versehen öffentlich machen: immer “Block Public Access” auf Account-Level aktivieren, außer du brauchst wirklich einen öffentlichen Bucket (z. B. statische Website).
  • Zu breite Policy geben ("Action": "*", "Resource": "*") für Test-Roles und dann vergessen zu entfernen vor Produktion.
  • MFA für Root-Account nicht aktivieren: Root-Account hat alle Rechte, sein Verlust ist das schlimmste Sicherheitsrisiko.
  • Access Keys in Code hart codieren: verwende IAM Role, Secrets Manager, oder Umgebungsvariablen durch CI/CD Secrets.
  • Falsche Region wählen führt zu hoher Latenz für Endbenutzer oder Verstoß gegen Anforderungen zur Datenspeicherung im In- oder Ausland.

7. Fazit

Region hilft dir, die richtige Infrastruktur-Position zu wählen und Latenz, Kosten und Compliance auszubalancieren. IAM ist die erste und wichtigste Schutzschicht — wende immer das Prinzip der geringsten Berechtigung an und bevorzuge Roles gegenüber statischen Access Keys. Mit Verständnis der Kern-Services (EC2, S3, RDS, Lambda, VPC) und deren Integration über AWS SDK hast du die nötige Grundlage, um ein echtes System auf AWS zu deployieren.

awscloudiamdevopsjava