AWS基礎:Region、IAMと主要サービス

1. 概要

このガイドでは、AWS初心者にとって最も重要な3つの柱を素早く学べます:region(インフラをどこに配置するか)、IAM(誰が何をできるか)、そして主要サービス(EC2、S3、RDS、Lambda、VPC…)。このガイドを読み終わったら、安全なAWSアカウント管理方法、アプリケーション用のIAM roleを作成する方法、そしてAWS SDK v2を使用してJavaからS3を呼び出すコードの書き方を理解できます。

2. RegionとAvailability Zone

AWSはインフラを複数のregion(地理的領域。例えばap-southeast-1(シンガポール))に分割し、各regionは複数の**Availability Zone (AZ)**を持ちます。これらは電力とネットワークで独立したデータセンターで、低レイテンシーのため近接していながら、故障を隔離(fault isolation)できます。

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

このコマンドはシンガポール region内のAZをリストアップします。結果は通常以下のような形式です:

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

システム設計時には、高可用性(high availability)のため最低2つのAZにデプロイすることをお勧めします。例えば、Auto Scaling GroupやRDS Multi-AZ instanceは、この原則に基づいています。

注意: IAM、Route 53、CloudFrontなど、一部のサービスはグローバル(特定のregionに関連付けられない)です。その他のほとんどのサービス(EC2、S3、RDS…)はregionalであり、設定しない限りデータは他のregionに自動的にレプリケートされません。

2.1. Regionの選択方法

3つの主な基準があります:レイテンシー(ユーザーに近い)、compliance(国内データ保管要件)、およびコスト(region間でサービス価格が異なります)。ベトナムのユーザーの場合、ap-southeast-1(シンガポール)は通常、低レイテンシーと充実したサービスのため、デフォルトの選択肢です。

3. IAM: User、Group、Role、Policy

IAM(Identity and Access Management)は、誰がどのリソースにアクセスできるかを制御します。4つの中核的な概念があります:

  • User:具体的なアイデンティティ(人またはサービス)で、独自の認証情報を持ちます。
  • Group:ユーザーの集合で、管理を簡単にするため共通のpolicyを適用します。
  • Role:一時的な権限セットで、固定の認証情報を持たず、EC2、Lambda、またはクロスアカウントアクセスに使用されます。
  • Policy:権限(allow/deny)をアクションとリソースに対して説明するJSON文書。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::order-invoices-bucket/*"
    }
  ]
}

このpolicyは、bucket order-invoices-bucket内のobjectの読み取り/書き込みを許可します。policyをroleに添付し、そのroleをInvoiceStorageServiceを実行するEC2 instanceまたはLambda functionにアタッチします。すると、アプリケーションはアクセスキー/シークレットキーをハードコードすることなく、自動的に権限を取得します。

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

最初のコマンドは、このroleを「assume」できる人(例:EC2 service)を定義するtrust-policy.jsonでroleを作成します。2番目のコマンドは、具体的なアクセス権policyをroleに添付します。

注意: アクセスキー/シークレットキーをコードに直接埋め込んだり、Gitにコミットしたりしないでください。IAM Role(AWSで実行されるリソース用)またはIAM Identity Center/SSO(ユーザー用)を使用してください。

3.1. 最小権限の原則

必要な権限だけを付与し、service accountにAdministratorAccess policyを使用しないでください。例えば、Lambdaがbucketを読む必要があるだけの場合、アカウント全体にs3:*を付与すべきではありません。

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

Deny statementは常に競合時にAllowより優先されます — これは、重要なbucketの誤削除を防ぐための「セーフティネット」を追加する方法です。

4. 主要サービス

4.1. Compute

  • EC2:時間/秒単位でレンタルできる仮想マシンで、OS管理は自分で行います。
  • Lambda:イベント駆動型でコードを実行し、サーバー管理は不要で、呼び出し回数と実行時間に基づいて課金されます。
  • ECS/EKS:Dockerコンテナをorchestrationして実行します。
aws lambda invoke \
  --function-name CalculateOrderTotal \
  --payload '{"orderId":"ORD-1001"}' \
  response.json

このコマンドはCalculateOrderTotal関数をペイロードJSONで呼び出し、結果をresponse.jsonに書き込みます。

4.2. Storage

  • S3:object storage、任意のファイル(画像、ログ、バックアップ)を保存でき、99.999999999%の耐久性を持ちます。
  • EBS:EC2にアタッチされるblock storage。
  • EFS:複数のEC2で共有マウント可能なfile system。

4.3. Database

  • RDS:管理型リレーショナルデータベース(MySQL、PostgreSQL…)で、自動バックアップとパッチ適用があります。
  • DynamoDB:NoSQL、自動スケーリング、一桁ミリ秒のレイテンシー。

4.4. Network

  • VPC:仮想プライベートネットワークで、subnet、route table、security groupを自分で定義します。
  • Security Group:instanceレベルでのステートフルファイアウォール。
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

このCloudFormationコードはOrderServiceSGという名前のSecurity Groupを作成し、ポート443(HTTPS)をすべてのIPに開きます。その他のインバウンドルールはデフォルトで拒否されます。

5. JavaアプリケーションからS3を呼び出す

このセクションでは、Spring Bootサービスから AWS SDK for Java v2を使用してS3にファイルをアップロードする方法を示します。

<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はコンストラクタを通じて注入されます(EC2/Lambdaで実行する場合、IAM Roleから認証情報を自動的に取得します。ハードコードは不要です)。uploadInvoiceメソッドは、keyをbucket内のobjectパスとしてPutObjectRequestを作成し、putObjectを呼び出してコンテンツをS3にプッシュします。

S3Client beanの設定:

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

credentialsProviderを明示的に渡す必要はありません — SDKはDefault Credentials Provider Chainを使用します:環境変数、~/.aws/credentialsファイル、その後EC2/ECS/LambdaにアタッチされたIAM Roleの順序で探します。

5.1. mock S3Clientでのテスト

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

    service.uploadInvoice("ORD-1001", "請求書の内容".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");
}

S3Clientをmock(Mockitoを使用)してCIを実行する際に実際のAWSを呼び出さないようにします。ArgumentCaptorは実際に送信されたPutObjectRequestをキャプチャし、AssertJがbucketとkeyが期待通りであることを検証します。ネットワークコストをかけずにリクエスト構築ロジックが正しいことを保証します。

注意: S3との統合テストを行う場合は、productionの実際のbucketを呼び出す代わりにLocalStackまたはTestcontainersライブラリを使用してください。コスト発生とデータリスクを避けることができます。

6. よくあるエラー

  • S3 bucketを誤ってpublicにする:実際に必要な場合(例:静的ウェブサイト)を除き、常にアカウントレベルで「Block Public Access」を有効にしてください。
  • policyが広すぎる("Action": "*", "Resource": "*")テストroleに適用してから、productionへの本番化時に削除し忘れる。
  • root accountのMFAを有効にしない:root accountは全権を持ち、rootアクセスを失うことは最大のリスクです。
  • コード内のアクセスキーをハードコードする:IAM Role、Secrets Manager、またはCI/CDシークレットを介した環境変数を使用してください。
  • regionを誤って選択する:エンドユーザーの高レイテンシー、またはデータ保管要件への違反につながります。

7. 結論

Regionは、レイテンシー、コスト、コンプライアンス間でインフラロケーションを正しく選択するのに役立ちます。IAMは最初で最も重要な保護層です。最小権限の原則を常に適用し、静的なアクセスキーよりもRoleを優先してください。コアサービス(EC2、S3、RDS、Lambda、VPC)と AWS SDKを通じた統合方法を習得することで、AWS上で実際のシステムをデプロイするための十分な基盤ができます。

awscloudiamdevopsjava