CloudFormationでVPC内のEC2インスタンスからS3バケットへの接続を実現

May
2024-08-06
2024-08-06

こんにちは。

今回はCloudFormationのテンプレートでVPC内のEC2インスタンスからS3 バケットへの接続についてをご紹介します。

事前にIAMユーザー作成

EC2インスタンスからS3バケットを使用できるようにするには、まず適切なアクセス許可を持つ  IAMユーザーを作成する必要があります。

今回の作業に取り掛かる前に、まずIAMユーザー作成のテンプレートを実行する必要があります。

IAMユーザーの作成方法については、以前詳しく説明したブログ記事を用意しました。まずは、こちらのブログ記事を確認してから、手順に従ってIAMユーザーの作成を事前に行ってください。

CloudFormationを使用して簡単にIAMユーザー作成

VPC内のEC2構築について

今回の作業に取り組む前に、以前ご紹介したブログ記事に記載されている「VPC内にEC2インスタンスを構築する方法」について一度ご確認いただければと思います。

これにより、VPCの設定やEC2インスタンスのデプロイ手順について、より具体的な理解が深まるかと思います。

CloudFormationを使用してVPC内に簡単にEC2構築してみる

今回の作業では、元テンプレートである「ec2_template.yaml」にS3バケット作成コードを追加し、VPC内のEC2インスタンスからS3バケットへの接続を実現します。

テンプレートにS3作成コード追加

ファイル名:ec2_template.yaml

元テンプレートにS3バケット作成のコードを追加致しました。

下記のテンプレートを使用してVPC内 → EC2インスタンス → S3バケットアクセス設定ができます。

S3バケットのパラメーターを指定できるようにするために、Input Parametersの設定に、緑の背景色で示されているコードを追加しました。

指定が無い場合、バケットの名はDefaultで指定している「test-s3-bucket」となります。

さらに、EC2インスタンスがS3バケットにアクセスするために必要なIAMロールを作成し、それを EC2インスタンスにアタッチしました。

S3 作成コードとIAMロール作成コードは緑の背景色で示されているコードです。

AWSTemplateFormatVersion:
  "2010-09-09"
Description: Provision EC2
# ------------------------------------------------------------#
# Input Parameters (Key Pair)
# ------------------------------------------------------------#
Parameters:
  KeyName:
    Type: "AWS::EC2::KeyPair::KeyName"
 
  VPCCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default:  172.32.10.0/24 ←CIDR IPは自分の環境と合わせて設定してください。
 
  PublicSubnetCIDR:
    Description: Please enter the IP range (CIDR notation) for the public subnet in the VPC
    Type: String
    Default: 172.32.10.0/24 ←CIDR IPは自分の環境と合わせて設定してください。
 
  S3BucketName:
    Description: Please enter the S3 Bucket Name
    Type: String
    Default: test-s3-bucket
Resources:
# ------------------------------------------------------------#
#  VPC作成
# ------------------------------------------------------------#
# VPC Create
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      # VPCのCidrblockはパラメータで指定する
      CidrBlock: !Ref VPCCIDR
      # VPC に対して DNS 解決がサポートされているか
      EnableDnsSupport: "true"
      # VPC 内に起動されるインスタンスが DNS ホスト名を取得するか
      EnableDnsHostnames: "true"
      # VPC 内に起動されるインスタンスの許可されているテナンシー
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: "test-vpc"

# InternetGateway Create
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: "test-igw"

# IGW Attach
  InternetGatewayAttachment:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

# ------------------------------------------------------------#
#  Public Subnet
# ------------------------------------------------------------#          
# Public Subnet Create
  PublicSubnet:
    Type: "AWS::EC2::Subnet"
    Properties:
      AvailabilityZone: "ap-northeast-1a"
      # VPCのPublic SubnetのCidrblockはパラメータで指定する
      CidrBlock: !Ref PublicSubnetCIDR
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "test-public-subnet"
# ------------------------------------------------------------#
#  RouteTable 
# ------------------------------------------------------------#          
# Public RouteTable Create
  PublicRouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: "test-public-route"

# ------------------------------------------------------------#
# Routing (ルーティング)
# ------------------------------------------------------------#
# PublicRoute Create
  PublicRoute:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

# ------------------------------------------------------------#
# RouteTable Associate
# ------------------------------------------------------------#
# PublicRouteTable Associate PublicSubnet
  PublicSubnetRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable
# ------------------------------------------------------------#
#  S3バケット作成
# ------------------------------------------------------------#
# S3 Bucket
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref S3BucketName
# ------------------------------------------------------------#
# s3 Access Point to VPC
# ------------------------------------------------------------#
  S3AccessPoint:
    Type: AWS::S3::AccessPoint
    Properties:
      Bucket: !Ref S3Bucket
      Name: my-access-point
      VpcConfiguration:
        VpcId: !Ref VPC
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        IgnorePublicAcls: true
        BlockPublicPolicy: true
        RestrictPublicBuckets: true
# ------------------------------------------------------------#
# IAMロールの作成
# ------------------------------------------------------------#
  S3AccessRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "ec2.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: EC2S3AccessPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:ListBucket
                Resource:
                  - !Sub "arn:aws:s3:::${S3Bucket}"
                  - !Sub "arn:aws:s3:::${S3Bucket}/*"
# インスタンスプロファイルの作成
  S3AccessInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: "/"
      Roles:
      - !Ref S3AccessRole
# ------------------------------------------------------------#
# WebServerセキュリティグループ作成
# ------------------------------------------------------------#
# WebServerセキュリティグループ
  WebServerSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: test-sg-group
      GroupDescription: web server test
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          #指定のIPから接続できるように設定する
          CidrIp: 0.0.0.0/0  ←CIDR IPは自分の環境と合わせて設定してください。
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          #指定のIPから接続できるように設定する
          CidrIp:0.0.0.0/0  ←CIDR IPは自分の環境と合わせて設定してください。
      Tags:
        - Key: Name
          Value: "test-sg-group"
# ------------------------------------------------------------#
# EC2インスタンス作成
# ------------------------------------------------------------#
# EC2インスタンス
  Ec2Instance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: ap-northeast-1a
      ImageId: ami-0329eac6c5240c99d
      IamInstanceProfile:
        !Ref S3AccessInstanceProfile
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      UserData:
          Fn::Base64: |
               #!/bin/bash
               sudo yum -y update
               sudo yum -y install httpd
               sudo systemctl start httpd.service
               sudo systemctl enable httpd.service
      NetworkInterfaces:
        # IPv4 アドレスを割り当てるか
        - AssociatePublicIpAddress: "true"
          # ------------------------------------------------------
          # アタッチの順序におけるネットワークインターフェイスの位置。
          # ネットワークインターフェイスを指定する場合必須
          # ------------------------------------------------------
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnet
          GroupSet:
            - !Ref WebServerSG
      Tags:
        - Key: Name
          Value: "test-server-spd"

※CidrIp:0.0.0.0/0 の場合、EC2にどこからでもアクセスできるようになりますので、セキュリティ的によろしくないです。実際に構築する時、接続したい環境のIPアドレスを指定してください。

テンプレートを使用する手順

1.AWS自アカウントにログインしてください。

2.検索枠に「cloudformation」を記入すると、検索結果に「CloudFormation」が表示されます。CloudFormationをクリックすると、CloudFormationパンネルに遷移されます。

3.「スタック作成」→「テンプレートファイルのアップロード」を選択 → 作成した「ec2_template.yaml」をアプロードして、「次へ」をクリックする。

5.スタック名記入画面が表示されます。スタック名を記入してください。

※Key Nameのところに、事前に準備したキーペアファイル名を記入してください。後「次へ」       をクリックする。

6.「次へ」をクリックすると、最後に確認画面が表示されて「送信」ボタンが表示されます。

「送信」をクリックすると下記のスタックを作成している画面が表示されます。ステータスのところに CREATE_IN_PROGRESSと表示されることが確認できます。

スタック作成完了したら、「CREATE_COMPLETE」に変わります。それで完成です。

EC2にSSHから接続確認

1.スタック作成完了後に、EC2パンネルに移行してインスタンスのところに作成したEC2インスタンスが表示されることが確認できます。

create success

2.EC2を選択し「接続」をクリックすると、インスタンスにSSHから接続する方法を確認できます。

ssh接続方法-2

3.SSH接続するため、ローカル環境のターミナルからsshディレクトリに行って、上記のSSHクライアントの手順通りコメント実行してください。

4.下記ようにターミナルからEC2に接続できることが確認できます。

ssh

EC2 に S3 接続用 IAM 情報設定追加

AWS のクラウドサービスをコマンドラインから操作するため、EC2 インスタンスに下記のAWS CLIの最新バージョンのインストール(linux)方法を使用してインストールする。

AWS CLIの最新バージョンのインストールまたは更新  

① curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

cli-install-1

➁ unzip awscliv2.zip でダウンロードされたインストーラを解凍します。

cli-install-2

③ sudo ./aws/install でインストールプログラムを実行します。

cli-install-3

④ aws --version コマンドを使用して、インストールを確認します。インストールされた、aws cli versionが表示されたら、AWS CLIインストール完了となります。

cli-install-4

EC2 から S3へ 接続アクセスのため、aws configure コマンドで IAM ユーザー設定をする。
※IAMユーザーのAccess KeyとSecret Access Keyが設定に必要ですので、「Secrets Manager」のパネルにある作成したcredentialsにAccess KeyとSecret Access Keyを確認してから作業を進めてください。

aws-configure

AWS Access Key ID : 確認した Access ID を記入
AWS Secret Access Key :  確認した Secret Access Key を記入
Default region name [ap-northeast-1] : ap-northeast-1
Default output format : json

S3バケットへの接続確認

下記のコマンドを実行して、EC2からS3バケットへの接続ができるか確認してください。

aws s3 ls

下記のように作成したS3 バケットが表示されたらアクセスできたということです。

s3 access check

以上です。最後まで読んでくれてありがとうございました。