いちはじCDK第13回 EC2パブリックIP編

AWS

いよいよサーバー構築

いよいよと言うか、やっとEC2にたどり着きましたね・・・
(。-`ω-)ホントだよっ
今回はEC2をパブリックIPを持っていて、キーペアを使ってアクセスするタイプで作ってみようかなと思います。
EC2インスタンスは、アクセスの仕方で作り方が違ってくるかと思いますが、個人的に扱うには一番オーソドックスな方法なんじゃないかなと思います。

EC2を作るのに必要なものを整理

EC2作るのには何が必要でしょう…それを一旦整理です。AWSだとEC2を作る前にあれも必要、これも必要みたいな感じで作らないといけないものがいくつも出てきます。
特にConstructがL1だと余計…そういうことを考えないとできないですね…
まずは構成図!今回は、パブリックなサブネットにおいて、キーペアを使ってアクセスするのが目標です。構成図はこんな感じです~

で必要なリソースは以下の感じになります。
・セキュリティグループ
・IAMロール
・インスタンスプロファイル
・EC2インスタンス
・キーペア
ってとこですかね!

キーペアをコンソールから作る!

キーペアはコンソールから作りましょう!
AWSのコンソール画面にアクセスして
サービス:EC2
→ネットワーク&セキュリティ
 →キーペア
です。

で…「キーペアを作成」をクリック!

以下の画面出てくるのでキーペアを作成しましょう。この先は、AWSコンソールが教えてくれるのでそれに従って作ってもらえたらいいんじゃないかと…
特に理由がなければRSAのまま、pemのままで良いです。

次に環境側を作っていきましょう

まずはVPC

VPCですが、今回インターネットGWを使うものを用意します。
いちはじCDK第4回 VPCとサブネット②」で作ったものとほとんど同じなんでここは省略して、出来上がりのソースのみGITで参照して下さい。
パラメータファイルはnyan_vpc.yamlになります。

セキュリティグループ

今回インターネットGW経由で外部と接続するので、入力としては以下を許可します。
ポート80番:HTTP用
ポート443番:HTTPS用
ポート22番:SSH用
セキュリティグループも難しいところはないんですが短いので抜粋して載せときます。
ec2.yamlの抜粋で該当箇所のパラメータリストのみ記載します。

---
PWorkInstance:
  securitygrps:
    pwork_instance_sg:
      id: "pwork_instance_sg"
      group_description: "PWork Instance OutPut SecurityGroup"
      group_name: "pwork_instance_sg"
      security_group_egress:
        - ip_protocol: "-1"
          cidr_ip: "0.0.0.0/0"
          description: "Allow all traffic."
      security_group_ingress:
        - ip_protocol: "tcp"
          cidr_ip: "0.0.0.0/0"
          from_port: 80
          to_port: 80
          description: "Allow HTTPS traffic."
      security_group_ingress:
        - ip_protocol: "tcp"
          cidr_ip: "0.0.0.0/0"
          from_port: 443
          to_port: 443
          description: "Allow HTTPS traffic."
      security_group_ingress:
        - ip_protocol: "tcp"
          cidr_ip: "0.0.0.0/0"
          from_port: 22
          to_port: 22
          description: "Allow SSH traffic."
      vpc_id: "{{pwork.vpcs.nyan_vpc.vpc_id}}"
      tags:
        - key: "module"
          value: "PworkInstance"

IAMロール

AWSが用意しているサービスロールAmazonEC2ContainerServiceforEC2Roleを使います。
それ以上の細かく説明できるところがないですね。
もしもっと、細かく権限設定したい場合は、AmazonEC2ContainerServiceforEC2Roleの定義を見て権限を厳しめにしていくと良いかと思います。
ec2.yamlの抜粋で該当箇所のパラメータリストのみ記載します。

---
PWorkInstance:
  securitygrps:
  …省略…
  roles:
    pwork_instance_role:
      id: "pwork_instance_role"
      role_name: "pwork_instance_role"
      description: "PWork Instance Role"
      assume_role_policy_document:
         "Version": "2012-10-17"
         "Statement":
           - "Effect": "Allow"
             "Action": "sts:AssumeRole"
             "Principal":
               "Service": "ec2.amazonaws.com"
      managed_policy_arns:
        - "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"

インスタンスプロファイルとEC2インスタンス

ここが鬼門ですね。インスタンスプロファイルはCfnInstanceProfileを使います。
EC2インスタンスはCfnInstanceを使います。
そもそもインスタンスプロファイルって何なのよ?って思いますよね?
AWSの公式ページでは、以下で説明されています。
インスタンスプロファイルを使用する
私の理解ではEC2インスタンスとIAMロールを紐づける役割がインスタンスプロファイルなのかなと思いました。気になる人は上記リンク読んでもらえると良いかと思います。
インスタンスプロファイルはそんなに難しくはないですね。
パラメータリストは以下になります。

---
PWorkInstance:
  securitygrps:
  …省略…
  instanceprofiles:
    pwork_instance_prof:
      id: "pwork_instance_prof"
      roles:
        - "{{PWorkInstance.roles.pwork_instance_role.ref}}"★IAMロールのところで定義したものを指定。
      instance_profile_name: "pwork_instance_prof"

続いてEC2インスタンスですね。こっちは、エグイ…パラメータが多いですよね。43個あります。
パラメータのザックリ説明は、りふぁれんすの方に簡単に記載しています。CfnInstanceを見て下さい。
ここでは、良く分からん、難しいものはパスして、使うもののみ簡単に説明したいと思います。
青字は今回のパラメータファイルで指定したものです。
・scope:省略
・id:省略
・additional_info:AWSが利用するパラメータなので我々ユーザーは利用できない。無視。
・affinity:特殊なパラメータなんで無視。
・availability_zone:動かしたいアベイラビリティゾーンを指定(例:ap-northeast-1a)
・block_device_mappings:起動時に関連付けするEBSまたはインスタンスボリュームを指定
・cpu_options:CPUコア数とスレッド数を指定できますが、特別なパターンなので使用しない。
・credit_specification:クレジットの標準、無制限の設定。ディフォルト標準。
・disable_api_termination:インスタンス終了時に削除しないようにするか指定する。
・ebs_optimized:インスタンスがAmazon EBS I/O用に最適化の指定。お金かかる。
・elastic_gpu_specifications:サービス終了しているので使用不可。無視。
・elastic_inference_accelerators:サービス終了しているので使用不可。無視。
・enclave_options:AWS Nitro Enclaves有効・無効の指定。特殊な指定なので無視。
・hibernation_options:インスタンスがスリープ状態になるかの指定。今回使わないので無視。
・host_id:Affinityパラメータを指定した時に指定する必要あるパラメータ。今回は無視。
・host_resource_group_arn:
・iam_instance_profile:上記で説明したものです。
・image_id:後で説明します。
・instance_initiated_shutdown_behavior:インスタンスシャットダウン時の停止か終了の指定
 ディフォルトは停止。いきなり終了にする人も少ないんじゃないかと思うしディフォルトでOK
・instance_type:t2.microとかを指定する。
・ipv6_address_count:IPv6アドレスを使うか時は必要。今回は無視
・ipv6_addresses:IPv6アドレスを使うか時は必要。今回は無視
・kernel_id:こちらも特殊な指定なので無視。
・key_name:上記で取得したキーペアの名前。
・launch_template:これも良くわからなかったけど、今回は必要ないんで無視。
・license_specifications:ライセンス?良くわからないので無視。
・metadata_options:IMDSv2を必須にしたりなどの指定。
 ディフォルト(必須)のままでよいので無視。
・monitoring:細かなモニタリングしたいときに有効にする。お金かかるので無視。
・network_interfaces:パブリックIPを使えるようにする指定。後で説明。
・placement_group_name:無視
・private_dns_name_options:無視
・private_ip_address:無視
・propagate_tags_to_volume_on_creation:無視
・ramdisk_id:無視
・security_group_ids:network_interfacesを指定するときはそっちで指定。今回は未指定
・security_groups:security_group_idsとの違いが解り難い…idじゃなくて名前で指定できる。
 ただ、ディフォルトVPCの場合しか上手く行かなかったと思う…記憶が曖昧。
 security_group_idsを使うのが無難。
・source_dest_check:無視
・ssm_associations:無視
・subnet_id:network_interfacesを指定するときはそっちで指定。今回は未指定
・tags:好きに設定すれば良い。
・tenancy:特別な設定無視。
・user_data:今回は未使用。ECS用のEC2インスタンスを作るときなんかは指定が必要。
・volumes:無視。
ということで長々書きましたが、今回使うのは9個ですね。43個からだいぶ絞れたかと思います。
実際のパラメータファイルの抜粋は以下になります。

---
PWorkInstance:
  securitygrps:
  …省略…
  instances:
    pwork_instance:
      id: "pwork_instance"
      availability_zone: "ap-northeast-1a"
      block_device_mappings:
        - device_name: "/dev/xvda"
          ebs:
            delete_on_termination: true
            encrypted: false
            iops: 3000
            volume_size: 8
            volume_type: "gp3"
      iam_instance_profile: "{{PWorkInstance.instanceprofiles.pwork_instance_prof.ref}}"
      image_id: "ami-09cd9fdbf26acc6b4"
      instance_type: "t2.micro"
      key_name: "{{common.key_pair}}"★作ったキーペアの名前を指定
      network_interfaces:
        - device_index: "0"
          delete_on_termination: true
          associate_public_ip_address: true
          group_set:
            - "{{PWorkInstance.securitygrps.pwork_instance_sg.attr_group_id}}"
          subnet_id: "{{pwork.subnets.nyan_pub_subnet_az1.attr_subnet_id}}"
      tags:
        - key: "module"
          value: "PworkInstance"
        - key: "Name"
          value: "PworkInstance"

image_id

image_idはOSなんかを何にしますか?って指定ですね。
色々な団体から公開されているものを使うことになります。
どこかのイメージを元に、自分でカスタマイズしたイメージも作れますが、今回はAWSさんが公開しているイメージを利用しようと思います。
image_idの確認手順は以下です。
①まずAWSアカウントにログインです。
②虫眼鏡の検索欄に「EC2」を入力して、サービスEC2をクリックです。
 最近EC2サービスにアクセスしたことある人は最近利用したサービスに既に出ている可能性ありますので、そちらからでもOKです。

③サイドメニューのイメージ→AMIカタログをクリック

④出てきた画面の以下の赤枠の部分がそうです。image_idのパラメータに指定してあるものと同じものです。使いたいのが他の場合は他のものでもOKです。(クリックで拡大されます。)

network_interfaces

network_inerfacesは、NetworkInterfacePropertyで詳細を指定します。
NetworkInterfacePropertyもパラメータがいくつかありますが、今回使っているものだけ説明します。
・device_index:
 ネットワークインタフェースの接続順番ってことですかね。
 「プライマリネットワークインターフェイスのデバイスインデックスは0です。」と説明があるので0を指定です。このパラメータ属性がstrなので“0”で指定。数値で指定するとエラーになります。
・delete_on_termination:
 インスタンス終了時にネットワークインタフェースを削除するかどうかの指定。削除したいのでTrueにしています。
・associate_public_ip_address:
 パブリックのIPアドレスを割り付けるかの指定。パブリックIPが欲しいのでTrueです。
・group_set:
 セキュリティグループのIDを指定。CfnInstanceのsecurity_group_idsを指定するとエラーになります。
・subnet_id:
 配置サブネットIDを指定。CfnInstanceのsubnet_idを指定するとエラーになります。

これで一通り説明したので、デプロイしてみましょう。

デプロイして確認ニン!

デプロイはしちゃったぜ!という体で説明します。
まずはVPCはこんな感じ…

これは雰囲気だけですね…こんな感じです…
次はEC2インスタンス。見せられないところは赤い四角で隠させてもらってます。
「詳細」などのタブは、イメージを省略します。

では「接続」をクリックして、接続方法を確認しましょう。

EC2 Instance Connect

パブリックIPを使用して接続と、プライベートIPを使用して接続というのがあります。
今回は当然、パブリックIPを使用して接続しかできないです。
こちらは下の「接続」をクリックするだけで簡単に接続できます。

Cloud Shellが起動して以下のようになります。

プライベート接続の方は、以下のようになります。EC2 Instance Connectエンドポイントのところで作成するを選ぶとおそらくプライベートIPでの接続も可能となりますが、VPCエンドポイントは高いのでやめておきます。

セッションマネージャー接続

次がSSM接続のタブです。前提条件を満たしてないので、この方法での接続は不可です。

SSHクライアント

こちらは接続可能です。例のところにあるコマンドで可能ですが、いくつか注意点あります。

ssh -i "キーペア名.pem" ec2-user@ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

私はWindows11の環境でPowerShellでやりました。キーペア名のところですが、「C:\Users\ユーザー名.ssh」にキーペア名.pemを入れておけば行けるのかな?と思いましたけど、ダメで。
以下の形でパスも指定しないとだめでした。

ssh -i "C:¥User\ユーザー名\.ssh\キーペア名.pem" ec2-user@ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

あと、キーペア名.pemファイルですが、権限を絞っておかないと接続エラーになります。
エラーのイメージを張っておきます。これが出たら、ファイル権限について見直して下さい。
Linuxだとchmodコマンドですけど、Windowsはちょっと違うので、以前「GITLABSSHキーの設定」で説明している方法でやると上手く行きます。

EC2 シリアルコンソール

EC2シリアルコンソール?って何?って思いましたね。そいうのがあるようです。
まずは公式HPから「EC2 シリアルコンソールに接続する」こちらを参照。
アカウントに対して、EC2シリアルアクセスを有効にして、IAMユーザーに対して権限を追加するなどしらできるようですが、今回はやりません。また機会あればやってみようかとも思いますが…と言う訳で今回は接続不可!です!

最後に自分のPCからTeraTermで繋ぐ

パブリックIPなんでTeraTermでも繋げるでしょうということでこちらもやってみます。
まずパブリックDNSをコピーです。以下赤枠です。

続いてTeraTermを起動。して以下の画面でホストに先ほどコピーしたパブリックDNSをコピーしてOKクリックです。

そうすると、以下の画面にたどり着くと思うので
ユーザー名:ec2-user
エージェント転送するのチェックを入れる
RSA/DSA/ECDSA/ED25519鍵を使うのオプションボタンを選んで、鍵の場所を指定。
でOKボタンをクリックです。

上手く行くと以下の感じで接続できます。

説明したかったことは以上ですね~
今回の前ソースはGITを参照してください~お疲れさまでした~

料金について

EC2インスタンスは、接続方法で作るものが変わってくると冒頭書きました。
方法としては以下の2つになりますかね。
①パブリックIPを付与して、インターネットゲートウェイ経由で接続する方法
②プライベートなサブネットにEC2インスタンスを配置してSSM接続する方法

②は外部接続がないけど接続できちゃうぞっていうところがセキュリティレベル高いとろころがポイントです。ただ、VPCエンドポイントと言うものが必要で、個人で使うには料金が高めになるのがデメリットかと思います。また、SSM接続はWEB画面でサーバーにアクセス可能ですが、TreaTermとかと勝手が違ってちょっと操作しにくいですね。

料金の比較してみましょう。
掛かる料金は
A:EC2インスタンス(オンデマンド)の使用料
B:DISKのEBSの使用料
C:通信される通信データ料
D:ネットワーク機器の料金(VPCエンドポイントや、パブリックIPアドレス)
こんなもんかなと…

上記のうちA~Cは、①のパブリックIP方式でも、②にSSM接続方式でも、同じと考えると、④の部分で料金の差が出てくるのかと思います。
(③はVPCエンドポイントと、パブリックIPアドレスだと違うがあるかもですが…)
料金は東京リージョンで算出しています。なお、算出時期は2026年1月現在になります。
場所、時期で料金が変わるので以下の説明は参考程度と思ってい下さい。

まずパブリックIPですが
過去IPv4アドレスには料金かからなかったのですが、最近は料金が発生するので、パブリックIPについても料金が掛かります。(ああ残念・・・)
その辺は以下のブログに説明書いてありますね。
「 パブリック IPv4 アドレスの利用に対する新しい料金体系を発表
Amazon VPC の料金」の説明から1時間0.005USDなので、月(×24×30)で3.6USDで1USD=140円で計算すると、約500円/月ってところですかね。

次にVPCエンドポイントの料金
SSM接続をするには、3つのVPCエンドポイントが必要になります。VPCエンドポイントも存在するだけでお金がかかって無効にするとかができないです。なので、お金がかからないようにするには削除するしかないです。
こちらも「AWS PrivateLink の料金」より1時間0.014USDなので、月(×24×30)で10.08USDで1USD=140円で計算すると、約1,420円/月くらいです。
SSM接続を利用するには3つのVPCエンドポイントが必要なので、約4,260円/月かかることになります。
パブリックIPより、3,760円高くなっちゃいますね。
個人的に使うなら、断然パブリックIPの方が良いんじゃないかと思います。
企業で使うような場合、キーペアをたくさん作らないといけないというのは管理的にもセキュリティ的にもやりたくはないのかなと感じますので、そういったときはSSM接続にするとスッキリするのではないでしょうか?
まぁ雑談なんですけど・・・次回はSSM接続をやってみようかと思います。(できたら)

コメント

タイトルとURLをコピーしました