新ネットワークスペシャリスト道

ネットワーク、セキュリティ、何の話?

【AWS 100日チャレンジ - 69日目】Reachability Analyzerを使用して疎通確認を行う。

AWSの知識を血肉にするための「AWS 100日チャレンジ」の69日目です。

今日は夜勤明けなので、連投します。

 

TransitGatewayをCloudFormationで作成したけど、

VPCXのEC2からVPCYへのPINGが通らない。

なぜ?

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

Reachability Analyzerを使用して疎通確認を行う。

実施 

ネットワークマネージャー
 >リーチャビリティアナライザー
  >パスの作成と分析を作成

 

送信元のEC2と送信先のEC2を指定する。

 

パスの分析をクリック。

 

確認をクリック。

 

数分たつと分析結果が出る。

「到達不可能」の表示が出ているのでどこでパケットが拒否されているのか詳細を見る。

内容を確認するとTransitgatewayのルートテーブルでばけっとが止まっている。

 

TransitGatewayのルートテーブルに伝播が作成されていなかったため、ルートがここで途絶えてしまっていた。

伝播(各VPCアタッチメント)を追加する。

 

疎通できた!

 

今回のAWS利用料金

◆Transit Gateway

①料金TGW本体料金: なし(作成自体は無料)

②アタッチメント料金: 0.07 USD / 時間 / 1アタッチメント

 計算: $0.07 × 2個 ×  730時間 = $ 102.20 USD

③データ処理料金: 0.02 USD / GB

 

 

【AWS 100日チャレンジ - 68日目】TransitGatewayをCloudFormationで生成する

AWSの知識を血肉にするための「AWS 100日チャレンジ」の68日目です。

 

昨日は夜勤でした。

11:00に起きたら、すごい雨

寒い。

 

先日手動で作成したTransitGatewayを

自動で生成できるようにします。

 

前提として、VPCX、VPCY、および各VPCのプライベートサブネットにEC2を構築。

作成時の記事 ↓

hlse.hateblo.jp

hlse.hateblo.jp

 

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

TransitGatewayをCloudFormationで生成する

実施 

TransitGatewayとVPCアタッチメント(各VPC)を自動生成する。

 

コードは以下。

VPCやサブネットは、VPCX、VPCYを生成するスタックのExportにて出力したものをImportする。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS Transit Gateway and VPC Attachments Template'

Resources:
  # ==========================================
  # 1. Transit Gateway 本体 の作成
  # ==========================================
  MyTransitGateway:
    Type: AWS::EC2::TransitGateway
    Properties:
      AmazonSideAsn: 64512
      AutoAcceptSharedAttachments: disable
      DefaultRouteTableAssociation: enable
      DefaultRouteTablePropagation: enable
      DnsSupport: enable
      VpnEcmpSupport: enable
      Tags:
        - Key: Name
          Value: main-transit-gateway

  # ==========================================
  # 2. X-VPC へのアタッチメント
  # ==========================================
  XVpcAttachment:
    Type: AWS::EC2::TransitGatewayAttachment
    Properties:
      TransitGatewayId: !Ref MyTransitGateway
      # 接続先リソース(VPC)の指定
      ResourceId: !ImportValue XXX-10-VPC # もしくは 'vpc-xxxxxx' などの直接指定
      # TGWがルートをルーティングするために各AZから最低1つのサブネットを指定
      SubnetIds:
        - !ImportValue XXX-10-PrivateMAIN-AZA
      Tags:
        - Key: Name
          Value: x-vpc-attach

  # ==========================================
  # 3. Y-VPC へのアタッチメント
  # ==========================================
  YVpcAttachment:
    Type: AWS::EC2::TransitGatewayAttachment
    Properties:
      TransitGatewayId: !Ref MyTransitGateway
      ResourceId: !ImportValue YYY-172-VPC
      SubnetIds:
        - !ImportValue YYY-172-PrivateMAIN-AZA
      Tags:
        - Key: Name
          Value: y-vpc-attach

Outputs:
  TransitGatewayId:
    Description: 'Created Transit Gateway ID'
    Value: !Ref MyTransitGateway
    Export:
      Name: !Sub "${AWS::StackName}-TGW-ID"

 

今回のAWS利用料金

◆Transit Gateway

①料金TGW本体料金: なし(作成自体は無料)

②アタッチメント料金: 0.07 USD / 時間 / 1アタッチメント

 計算: $0.07 × 2個 ×  730時間 = $ 102.20 USD

③データ処理料金: 0.02 USD / GB

 

 

【AWS 100日チャレンジ - 67日目】VPCXとVPCYをTransit Gatewayで相互通信を行う

AWSの知識を血肉にするための「AWS 100日チャレンジ」の67日目です。

 

5月とは思えない暑さ。

業務は外出で日中外に出ると熱気がすごかった。

はやいだろ、夏。

 

数日前に作成したVPC(EC2あり)にフリートマネージャでリモートできるようにした環境を使用して、Transitgatewayを試してみる。

hlse.hateblo.jp

hlse.hateblo.jp

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

VPCXとVPCYをTransit Gatewayで相互通信を行う

実施 

 

Transit Gateway の作成

 

Transitgatewayの名前だけ入力し作成。

 

数十秒で使用可能となった。

 

VPC のアタッチメント(接続)作成

各VPCのTWアタッチメントを作成

1つ目のアタッチメント(YYY-172-vpc用)

アタッチメント名:vpcy-transitgateway-attach

 

1つ目のアタッチメント(XXX-10-vpc用)

アタッチメント名:vpcx-pvcy-transitgateway-attach



 

VPC 側のルートテーブルの編集

XXX-10-vpc のメインルートテーブルを開く。

[ルートを編集] をクリックし、以下のルートを追加。

送信先: 172.16.0.0/16 (相手のCIDR)

ターゲット: 作成した TGW を選択

 

YYY-172-vpc のメインルートテーブルを開く。

[ルートを編集] をクリックし、以下のルートを追加。

送信先: 10.1.0.0/16 (相手のCIDR)

ターゲット:  作成した TGW を選択

 

 

セキュリティグループの緩和(PINGの許可)

インバウンドルールをそれぞれのEC2に追加。

 

XXX-10-vpc 側のEC2のセキュリティグループ:

タイプ: すべての ICMP - IPv4 (またはカスタムICMPの「エコー要求」)

ソース: 172.16.0.0/16

 

YYY-172-vpc 側のEC2のセキュリティグループ:

タイプ: すべての ICMP - IPv4

ソース: 10.1.0.0/16

 

疎通確認(PING実行)

10.1.100.10/24にリモートし172.16.100.10/24へPINGを打つ

172.16.100.10/24にリモートし10.1.100.10/24へPINGを打つ

 

成功!

 

今回のAWS利用料金

◆Transit Gateway

①料金TGW本体料金: なし(作成自体は無料)

②アタッチメント料金: 0.07 USD / 時間 / 1アタッチメント

 計算: $0.07 × 2個 ×  730時間 = $ 102.20 USD

③データ処理料金: 0.02 USD / GB

 

SSMで使用しているVPCエンドポイントは今回は無視。

 

【AWS 100日チャレンジ - 66日目】VPCXとVPCYをVPCピアリングで相互通信を行う

AWSの知識を血肉にするための「AWS 100日チャレンジ」の66日目です。

今日は夏並みに扱った。

夜も熱気がマンションにこもってます。

 

以下記事でネットワーク検証する環境を自動生成するCloudFormationスタックファイルを作成。

 

hlse.hateblo.jp

hlse.hateblo.jp

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

VPCXとVPCYをVPCピアリングで相互通信を行う

実施 

 

VPC ピアリング接続の作成

片方の VPC からもう片方の VPC へ接続リクエストを送信し、それを承認する。

リクエスタ:VPCX

アクセプタ:VPCY

まずは、ピアリング接続を作成。

作成したVPCピアリングをクリック。


以下の状態になっている。

 

アクションから「リクエストを承諾」をクリック

 

 

ルートテーブルの更新

両方のルートテーブルにルートを追加する。

・XXX-10-vpc 側の設定

送信先: 172.16.0.0/16

ターゲット:作成したVPCピアリング

 

・YYY-172-vpc 側の設定

送信先: 10.1.0.0/16

ターゲット:作成したVPCピアリング

 

セキュリティグループの変更

・XXX-10-vpc 側の設定

タイプ: すべての ICMP - IPv4

ソース: 172.16.0.0/16

 

・YYY-172-vpc 側の設定

タイプ: すべての ICMP - IPv4

ソース: 10.1.0.0/16

 

動作確認

確認 10.1.100.10 > 172.16.100.10

 

確認 172.16.100.10 > 10.1.100.10

 

 

今回のAWS利用料金

同AZなら無料で使用可能そう

①VPC ピアリング接続の作成・維持 : 無料

②データ転送量 : 同AZは無料。 異AZは$0.01/GB(東京リージョンの場合)

 

 

 

【AWS 100日チャレンジ - 65日目】VPCXとVPCYのプライベートサブネットに存在するEC2にフリートマネージャでリモート可能にする

AWSの知識を血肉にするための「AWS 100日チャレンジ」の65日目です。

 

前回記事ででとりあえず、VPCを2個とそれぞれにEC2を構築済み。

 

hlse.hateblo.jp

 

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

VPCXとVPCYのプライベートサブネットに存在するEC2にフリートマネージャでリモート可能にする

実施 

とりあえずVPCとEC2関連は作成できたので、

次にお互いに疎通ができているかPINGを打てるように

フリートマネージャでリモートできるようにする。

 

とりあえず、3つのインターフェース型VPCエンドポイントを作成。

 

EC2を再起動するとフリーとマネージャに表示されていた。

 

 

Cloudformation化しておきます。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template to create VPC Endpoints for AWS Systems Manager (SSM) Session Manager.'

Resources:
  # ==========================================================
  # 1. VPCエンドポイント用のセキュリティグループ
  # ==========================================================
  VPCEndpointSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'Security Group for SSM VPC Endpoints'
      VpcId: !ImportValue XXX-10-VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: 'ssm-vpce-sg'

  # ==========================================================
  # 2. VPCエンドポイント: ssm
  # ==========================================================
  SSMEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
      VpcId: !ImportValue XXX-10-VPC
      SubnetIds: [ {"Fn::ImportValue": "XXX-10-PrivateMAIN-AZA"} ]
      SecurityGroupIds:
        - !Ref VPCEndpointSecurityGroup
      PrivateDnsEnabled: true

  # ==========================================================
  # 3. VPCエンドポイント: ssmmessages
  # ==========================================================
  SSMMessagesEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
      VpcId: !ImportValue XXX-10-VPC
      SubnetIds: [ {"Fn::ImportValue": "XXX-10-PrivateMAIN-AZA"} ]
      SecurityGroupIds:
        - !Ref VPCEndpointSecurityGroup
      PrivateDnsEnabled: true

  # ==========================================================
  # 4. VPCエンドポイント: ec2messages
  # ==========================================================
  EC2MessagesEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: Interface
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2messages'
      VpcId: !ImportValue XXX-10-VPC
      SubnetIds: [ {"Fn::ImportValue": "XXX-10-PrivateMAIN-AZA"} ]
      SecurityGroupIds:
        - !Ref VPCEndpointSecurityGroup
      PrivateDnsEnabled: true

Outputs:
  SSMEndpointId:
    Description: 'SSM Endpoint ID'
    Value: !Ref SSMEndpoint
  SSMMessagesEndpointId:
    Description: 'SSM Messages Endpoint ID'
    Value: !Ref SSMMessagesEndpoint
  EC2MessagesEndpointId:
    Description: 'EC2 Messages Endpoint ID'
    Value: !Ref EC2MessagesEndpoint

 

今日はここまで。

次もTransitGatewayの各機能を検証する準備をしていきます。

 

【AWS 100日チャレンジ - 64日目】AWSネットワークを検証するためのVPCXとVPCYとVPCZを構築

AWSの知識を血肉にするための「AWS 100日チャレンジ」の64日目です。

 

家庭の事情でいろいろあり63日連続で途絶えてしまった。。。

今日から64日目から始めます。

 

AWS Certified SysOps Administrator - Associateは合格したので、つぎは、AWS ANS(AWS Certified Advanced Networking - Specialty)の勉強。

 

このチャレンジが100日目になったときに試験を受けたい。

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

VPCAとVPCBをTransitGatewayで相互通信を行う

核VPCのCIDRはなんちゃってクラスフル

VPCX 10系

VPCY 172系

VPCZ 192系

実施 

まずこの検証を行うに当たり、

VPCA(EC2あり)とVPCB(EC2あり)を構築する。

もちろんCloudFormationでVPCAとEC2をプライベートサブネットに作成。

 

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC-10

Parameters:
  # ------------------------------------------------------------#
  # Common
  # ------------------------------------------------------------#
  Prefix:
    Type: String
    Default: 'XXX-10'
  Cider:
    Type: String
    Default: '10.1.0.0/16'
  CiderPublicSubnet:
    Type: String
    Default: '10.1.1.0/24'
  CiderPrivateSubnet:
    Type: String
    Default: '10.1.100.0/24'
  InstanceImageIdLinux:
    Description: 'The AMI ID for the EC2 instance(Linux)'
    Type: 'AWS::EC2::Image::Id'
    Default: 'ami-08f0737412a47a5ed' # 例: Amazon Linux 2 AMI (必要に応じて変更可能)
  KeyName:
    Description: 'Name of an existing EC2 KeyPair to enable SSH access'
    Type: 'AWS::EC2::KeyPair::KeyName'
    Default: 'ALLKEY20260110'
  PrivateIpAddress:
    Type: String
    Description: 'EC2 IP'
    Default: '10.1.100.10'

Resources:
  # VPCの作成
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Sub '${Cider}'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-vpc'
  # インターネットゲートウェイの作成
  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  # VPCとインターネットゲートウェイを接続
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref MyInternetGateway

  # パブリックサブネット
  # ルートテーブル
  RouteTablePublicMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-Routepublicsubnet'
  # ルートテーブルへのルート登録 IGWへのルート
  RoutePublicMAIN:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref RouteTablePublicMAIN
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGateway
  # ルートとサブネット紐づけ
  RouteTableAssocPublic01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicMAINAZA
      RouteTableId: !Ref RouteTablePublicMAIN
  # パブリックサブネット1の作成
  PublicMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPublicSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      MapPublicIpOnLaunch: false
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PublicMAIN-AZA'

  # プライベートサブネット
  # ルートテーブル
  RouteTablePrivateMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-RoutePrivatesubnet'
  # ルートとサブネット紐づけ
  RouteTableAssocPrivate01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateMAINAZA
      RouteTableId: !Ref RouteTablePrivateMAIN
  # プライベートサブネットの作成
  PrivateMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPrivateSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: !Sub '${Prefix}-Private-SG'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSG'
  # EC2
  LinuxSvA:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: 't2.micro'
      ImageId: !Ref InstanceImageIdLinux
      SubnetId: !Ref PrivateMAINAZA
      PrivateIpAddress: !Ref PrivateIpAddress
      SecurityGroupIds:
        - !Ref LinuxSG
      KeyName: !Ref KeyName
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSvA'
      # ユーザーデータからWebサーバーをインストールする
      UserData:
       Fn::Base64: !Sub |
        #!/bin/bash
        # サーバーの設定変更
        sudo sed -i 's/^HOSTNAME=[a-zA-Z0-9\.\-]*$/HOSTNAME=LinuxSrv/g' /etc/sysconfig/network
        sudo hostname '${Prefix}-LinuxSvA'
        sudo cp /usr/share/zoneinfo/Japan /etc/localtime
        sudo timedatectl set-timezone Asia/Tokyo
        sudo echo 'LANG=ja_JP.UTF-8' | sudo tee /etc/sysconfig/i18n
        sudo yum install httpd -y
        sudo systemctl enable httpd
        sudo systemctl start httpd
        TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
        PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4)
        echo "Hello World! Linux $HOSTNAME, IP:$PUBLIC_IP" | sudo tee /var/www/html/index.html

Outputs:
  VPCId:
    Description: 'VPC ID'
    Value: !Ref VPC
    Export:
      Name: !Sub '${Prefix}-VPC'

  PublicMAINAZAId:
    Description: 'Public Subnet'
    Value: !Ref PublicMAINAZA
    Export:
      Name: !Sub '${Prefix}-PublicMAIN-AZA'

  PrivateMAINAZAId:
    Description: 'Private Subnet'
    Value: !Ref PrivateMAINAZA
    Export:
      Name: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSvA:
    Description: 'EC2 Instance ID'
    Value: !Ref LinuxSvA
    Export:
      Name: !Sub '${Prefix}-LinuxSvA'

  # MyEC2InstanceLinux2:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceLinux2

  # MyEC2InstanceWindows:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceWindows

 

VPCYも同様に作成。

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC-172

Parameters:
  # ------------------------------------------------------------#
  # Common
  # ------------------------------------------------------------#
  Prefix:
    Type: String
    Default: 'YYY-172'
  Cider:
    Type: String
    Default: '172.16.0.0/16'
  CiderPublicSubnet:
    Type: String
    Default: '172.16.1.0/24'
  CiderPrivateSubnet:
    Type: String
    Default: '172.16.100.0/24'
  InstanceImageIdLinux:
    Description: 'The AMI ID for the EC2 instance(Linux)'
    Type: 'AWS::EC2::Image::Id'
    Default: 'ami-08f0737412a47a5ed' # 例: Amazon Linux 2 AMI (必要に応じて変更可能)
  KeyName:
    Description: 'Name of an existing EC2 KeyPair to enable SSH access'
    Type: 'AWS::EC2::KeyPair::KeyName'
    Default: 'ALLKEY20260110'
  PrivateIpAddress:
    Type: String
    Description: 'EC2 IP'
    Default: '172.16.100.10'

Resources:
  # VPCの作成
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Sub '${Cider}'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-vpc'
  # インターネットゲートウェイの作成
  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  # VPCとインターネットゲートウェイを接続
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref MyInternetGateway

  # パブリックサブネット
  # ルートテーブル
  RouteTablePublicMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-Routepublicsubnet'
  # ルートテーブルへのルート登録 IGWへのルート
  RoutePublicMAIN:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref RouteTablePublicMAIN
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGateway
  # ルートとサブネット紐づけ
  RouteTableAssocPublic01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicMAINAZA
      RouteTableId: !Ref RouteTablePublicMAIN
  # パブリックサブネット1の作成
  PublicMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPublicSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      MapPublicIpOnLaunch: false
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PublicMAIN-AZA'

  # プライベートサブネット
  # ルートテーブル
  RouteTablePrivateMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-RoutePrivatesubnet'
  # ルートとサブネット紐づけ
  RouteTableAssocPrivate01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateMAINAZA
      RouteTableId: !Ref RouteTablePrivateMAIN
  # プライベートサブネットの作成
  PrivateMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPrivateSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: !Sub '${Prefix}-Private-SG'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSG'
  # EC2
  LinuxSvA:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: 't2.micro'
      ImageId: !Ref InstanceImageIdLinux
      SubnetId: !Ref PrivateMAINAZA
      PrivateIpAddress: !Ref PrivateIpAddress
      SecurityGroupIds:
        - !Ref LinuxSG
      KeyName: !Ref KeyName
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSvA'
      # ユーザーデータからWebサーバーをインストールする
      UserData:
       Fn::Base64: !Sub |
        #!/bin/bash
        # サーバーの設定変更
        sudo sed -i 's/^HOSTNAME=[a-zA-Z0-9\.\-]*$/HOSTNAME=LinuxSrv/g' /etc/sysconfig/network
        sudo hostname '${Prefix}-LinuxSvA'
        sudo cp /usr/share/zoneinfo/Japan /etc/localtime
        sudo timedatectl set-timezone Asia/Tokyo
        sudo echo 'LANG=ja_JP.UTF-8' | sudo tee /etc/sysconfig/i18n
        sudo yum install httpd -y
        sudo systemctl enable httpd
        sudo systemctl start httpd
        TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
        PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4)
        echo "Hello World! Linux $HOSTNAME, IP:$PUBLIC_IP" | sudo tee /var/www/html/index.html

Outputs:
  VPCId:
    Description: 'VPC ID'
    Value: !Ref VPC
    Export:
      Name: !Sub '${Prefix}-VPC'

  PublicMAINAZAId:
    Description: 'Public Subnet'
    Value: !Ref PublicMAINAZA
    Export:
      Name: !Sub '${Prefix}-PublicMAIN-AZA'

  PrivateMAINAZAId:
    Description: 'Private Subnet'
    Value: !Ref PrivateMAINAZA
    Export:
      Name: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSvA:
    Description: 'EC2 Instance ID'
    Value: !Ref LinuxSvA
    Export:
      Name: !Sub '${Prefix}-LinuxSvA'

  # MyEC2InstanceLinux2:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceLinux2

  # MyEC2InstanceWindows:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceWindows

 

さらにVPCZを作成。

AWSTemplateFormatVersion: '2010-09-09'
Description: VPC-192

Parameters:
  # ------------------------------------------------------------#
  # Common
  # ------------------------------------------------------------#
  Prefix:
    Type: String
    Default: 'ZZZ-192'
  Cider:
    Type: String
    Default: '192.168.0.0/16'
  CiderPublicSubnet:
    Type: String
    Default: '192.168.1.0/24'
  CiderPrivateSubnet:
    Type: String
    Default: '192.168.100.0/24'
  InstanceImageIdLinux:
    Description: 'The AMI ID for the EC2 instance(Linux)'
    Type: 'AWS::EC2::Image::Id'
    Default: 'ami-08f0737412a47a5ed' # 例: Amazon Linux 2 AMI (必要に応じて変更可能)
  KeyName:
    Description: 'Name of an existing EC2 KeyPair to enable SSH access'
    Type: 'AWS::EC2::KeyPair::KeyName'
    Default: 'ALLKEY20260110'
  PrivateIpAddress:
    Type: String
    Description: 'EC2 IP'
    Default: '192.168.100.10'

Resources:
  # VPCの作成
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Sub '${Cider}'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-vpc'
  # インターネットゲートウェイの作成
  MyInternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  # VPCとインターネットゲートウェイを接続
  AttachGateway:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref MyInternetGateway

  # パブリックサブネット
  # ルートテーブル
  RouteTablePublicMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-Routepublicsubnet'
  # ルートテーブルへのルート登録 IGWへのルート
  RoutePublicMAIN:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref RouteTablePublicMAIN
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGateway
  # ルートとサブネット紐づけ
  RouteTableAssocPublic01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicMAINAZA
      RouteTableId: !Ref RouteTablePublicMAIN
  # パブリックサブネット1の作成
  PublicMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPublicSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      MapPublicIpOnLaunch: false
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PublicMAIN-AZA'

  # プライベートサブネット
  # ルートテーブル
  RouteTablePrivateMAIN:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${Prefix}-RoutePrivatesubnet'
  # ルートとサブネット紐づけ
  RouteTableAssocPrivate01:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateMAINAZA
      RouteTableId: !Ref RouteTablePrivateMAIN
  # プライベートサブネットの作成
  PrivateMAINAZA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Sub '${CiderPrivateSubnet}'
      AvailabilityZone: 'ap-northeast-1a'
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: !Sub '${Prefix}-Private-SG'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSG'
  # EC2
  LinuxSvA:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: 't2.micro'
      ImageId: !Ref InstanceImageIdLinux
      SubnetId: !Ref PrivateMAINAZA
      PrivateIpAddress: !Ref PrivateIpAddress
      SecurityGroupIds:
        - !Ref LinuxSG
      KeyName: !Ref KeyName
      Tags:
        - Key: 'Name'
          Value: !Sub '${Prefix}-Private-LinuxSvA'
      # ユーザーデータからWebサーバーをインストールする
      UserData:
       Fn::Base64: !Sub |
        #!/bin/bash
        # サーバーの設定変更
        sudo sed -i 's/^HOSTNAME=[a-zA-Z0-9\.\-]*$/HOSTNAME=LinuxSrv/g' /etc/sysconfig/network
        sudo hostname '${Prefix}-LinuxSvA'
        sudo cp /usr/share/zoneinfo/Japan /etc/localtime
        sudo timedatectl set-timezone Asia/Tokyo
        sudo echo 'LANG=ja_JP.UTF-8' | sudo tee /etc/sysconfig/i18n
        sudo yum install httpd -y
        sudo systemctl enable httpd
        sudo systemctl start httpd
        TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
        PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-ipv4)
        echo "Hello World! Linux $HOSTNAME, IP:$PUBLIC_IP" | sudo tee /var/www/html/index.html

Outputs:
  VPCId:
    Description: 'VPC ID'
    Value: !Ref VPC
    Export:
      Name: !Sub '${Prefix}-VPC'

  PublicMAINAZAId:
    Description: 'Public Subnet'
    Value: !Ref PublicMAINAZA
    Export:
      Name: !Sub '${Prefix}-PublicMAIN-AZA'

  PrivateMAINAZAId:
    Description: 'Private Subnet'
    Value: !Ref PrivateMAINAZA
    Export:
      Name: !Sub '${Prefix}-PrivateMAIN-AZA'

  LinuxSvA:
    Description: 'EC2 Instance ID'
    Value: !Ref LinuxSvA
    Export:
      Name: !Sub '${Prefix}-LinuxSvA'

  # MyEC2InstanceLinux2:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceLinux2

  # MyEC2InstanceWindows:
  #   Description: 'EC2 Instance ID'
  #   Value: !Ref MyEC2InstanceWindows

 

 

最初からgeminiとかに作成してもらったら楽なのですが、

勉強にならんので自分で作成。

 

とりあえず今後AWSネットワークを検証するうえで使いまわせるCloudFormationのテンプレートが作成できた。

 

【AWS 100日チャレンジ - 63日目】Lambda による S3 アップロード時の自動画像変換(またはログ記録)

AWSの知識を血肉にするための「AWS 100日チャレンジ」の63日目です。

 

AWS 100日チャレンジの記事を書く上でのルール

・100日連続アウトプット!

・継続が第一、クオリティは第二

・「社会人のリアル」を忘れない(持続可能な完走を目指す)

・コアな学習に全集中!
 テーマとするサービス以外は、CloudFormationや構築済みの資産をフル活用。効率よく「核心」を突き詰めます。

課題

Lambda による S3 アップロード時の自動画像変換(またはログ記録)

実施 

1.S3バケット作成

変換元と変換先のバケット作成

変換元:xxx-source-image-backet

変換先:xxx-after-image-bakchet

バケット名だけ入力しあとはデフォルト設定で作成。

 

2.IAM ロールの作成

IAMロール名:xxx-imagechange-role

許可ポリシー:

 AmazonS3FullAccess

 AWSLambdaBasicExecutionRole

 

3.Lambda 関数の作成

lambda名:xxx-imagechange-function

関数を作成 :一から作成

そのほかはデフォルト。

 

ソースコードは以下。

import boto3
import os
import sys
import uuid
from PIL import Image

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    # イベントからバケット名とファイル名を取得
    source_bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    
    # ログ記録
    print(f"File uploaded: {key} in bucket {source_bucket}")

    # 出力先バケットの設定
    dest_bucket = "xxx-after-image-bakchet"
    download_path = f"/tmp/{uuid.uuid4()}{key}"
    upload_path = f"/tmp/resized-{key}"

    # S3から画像をダウンロード
    s3_client.download_file(source_bucket, key, download_path)

    # 画像リサイズ処理
    with Image.open(download_path) as image:
        image.thumbnail*1 # 例:最大128pxにリサイズ
        image.save(upload_path)

    # S3にアップロード
    s3_client.upload_file(upload_path, dest_bucket, f"resized-{key}")
    
    print(f"Successfully resized and uploaded to {dest_bucket}")

 

手順2で作成したロールをlambdaに設定

 

 

トリガーを追加。

 

 

一般設定タブをクリック。

 

メモリを512MBにして、タイムアウトを1分に設定。

 

 

Lambda の標準環境には画像処理ライブラリ Pillow が入っていないため、外部から持ち込む必要がある。

そのためにレイヤーが必要。

 

レイヤーを事前に登録

 

レイヤーの追加をクリック。

 

今日はここまで、明日に続けます。

 

*1:128, 128