MENU

AWS CDKでインフラ構築⑥(Amazon Linuxでyum updateができない問題を解決する)

やりたいこと

プライベートサブネットに立てたEC2インスタンスyum update を叩いたところエラーになってしまった。

困るので、なんとかして yum コマンドを叩けるようにしたい。

どんなエラーがでるのか

yum update を叩いたところこんなメッセージが表示された。

Could not retrieve mirrorlist http://repo.us-east-1.amazonaws.com/latest/main/mirror.list error was
12: Timeout on http://repo.us-east-1.amazonaws.com/latest/main/mirror.list: (28, 'Connection timed out after 5001 milliseconds')

One of the configured repositories failed (Unknown),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Run the command with the repository temporarily disabled
            yum --disablerepo=<repoid> ...

     4. Disable the repository permanently, so yum won't use it by default. Yum
        will then just ignore the repository until you permanently enable it
        again or use --enablerepo for temporary usage:

            yum-config-manager --disable <repoid>
        or
            subscription-manager repos --disable=<repoid>

     5. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true

こんな感じのエラーで、 http://repo.us-east-1.amazonaws.com/latest/main/mirror.list にアクセスしようとしてタイムアウトを起こしているということだけはわかった。

なんでこうなっているのか

AmazonLinuxのyumリポジトリにアクセスできないのが原因。

AmazonLinux(AmazonLinux2)は、yumリポジトリがS3に存在しているらしい。(知らなかった...)

で、私が立てたEC2インスタンスはS3と通信できるような設定は施していないのでタイムアウトが起きていた。

解消方法

EC2インスタンスがS3と通信できるように構成を修正していきます。

具体的にやることとしては、下記の通りです。

  • VPCにS3用のエンドポイントを追加する。

  • EC2のIAMロールに、S3にアクセスするためのポリシーを追加する。

VPCにS3用のエンドポイントを追加する。

EC2からS3に接続するには、下記のエンドポイントを作る必要があります。

  • com.amazonaws.[vpcRegion].s3

[留意点]

  1. エンドポイントポイントはGateway型を選択すると設定が楽

あんまりよくわかっていないが、Gateway型を選択するとセキュリティグループ等の設定が必要なくなる。

どうやら、EC2がプライベートサブネットに存在していてもGateway型エンドポイントが上手いことやってくれているらしい

参考:2つのVPCエンドポイントの違いを知る | DevelopersIO

  1. ルートテーブルにはエンドポイントと紐づけたいEC2に適用されているルートテーブルを指定する。

EC2のIAMロールに、S3にアクセスするためのポリシーを追加する。

EC2インスタンス作成はCDKでやっているので、ロール付与もCDKでやってしまいます。 (テスト用なのでFullAccessを指定してしまいましたが、実際運用するとなるともっと権限絞る必要があると思います)

// EC2用のロールを作成
    const ec2Role = new iam.Role(this, 'ec2-role', {
      assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName(
          "AmazonS3FullAccess"
        ),
      ],
      roleName: `cdk-test-ec2-role`
    });

これで yum update が通るようになりました。

これでもだめだった場合

公式 によると、ネットワーク設定が下記に合致している必要があるみたいです。

- EC2 インスタンスにアタッチされたセキュリティグループで、アウトバウンド http トラフィックが許可されている。
 
- S3 VPC エンドポイントにアタッチされたセキュリティグループで、EC2 インスタンスのサブネットからのインバウンド http トラフィックが許可されている。
 
- EC2 インスタンスのサブネットに関連付けられているネットワーク ACL で、以下が許可されている。
  - ポート 80 (http) および 443 (HTTPS) でのリージョナル S3 サービスへの出力。
  - ネットワーク ACL に S3 CIDR を追加するには、S3 CIDR として 0.0.0.0/0 を使用します。

参考