やりたいこと
プライベートサブネットに立てた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
[留意点]
- エンドポイントポイントはGateway型を選択すると設定が楽
あんまりよくわかっていないが、Gateway型を選択するとセキュリティグループ等の設定が必要なくなる。
どうやら、EC2がプライベートサブネットに存在していてもGateway型エンドポイントが上手いことやってくれているらしい
参考:2つのVPCエンドポイントの違いを知る | DevelopersIO
- ルートテーブルにはエンドポイントと紐づけたい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 を使用します。