はじめに
プライベートサブネットに配置しているEC2に対してインストールしたいアプリやセキュリティパッチなどを当てたい場合、一般的にはインターネットに接続する必要があります。
ただ、Amazon Linuxにおいてはインターネットにアクセスせずに更新したりパッケージのインストールができたりします。詳細は以下を参照してください。
以下では、Amazon Linux 2023においてプライベートサブネットにおいたインスタンスにパッケージのインストールをすることをCDKで実装してみます。
VPC作成
VPCを作成します。natGateways
を0にしておきます。
const vpc = new Vpc(this, 'VPC', { cidr: '10.0.0.0/16', vpcName: 'MyRDSTestVPC', natGateways: 0, maxAzs: 2, subnetConfiguration: [ { // EC2用のprivate subnet cidrMask: 24, name: 'forEC2', subnetType: SubnetType.PRIVATE_WITH_EGRESS } ] });
S3へのアクセスパスを設定
// GatewayタイプのVPCエンドポイントを作成する vpc.addGatewayEndpoint('s3Endpoint', { service: GatewayVpcEndpointAwsService.S3, subnets: [{ subnetType: SubnetType.PRIVATE_WITH_EGRESS }] });
準備は以上で完了です。
EC2作成時にパッケージのインストールを実行する
EC2作成時に適当にパッケージをインストールする処理を書いてみます。詳細は以下のドキュメントにあるユーザーデータを使用します。
CDKでの実装は以下の通り。今回はMariaDBとPostgreSQLをインストールしてみます。
const userData = UserData.forLinux({ shebang: '#!/bin/bash', }); userData.addCommands( 'dnf install -y mariadb105', 'dnf install -y postgresql15' );
dnfコマンドに-y
オプションをつけておく必要があります。これをつけていない場合はインストールがされません。
EC2インスタンスの作成
EC2インスタンスを作成します。上記で作成したuserData
はuserData
プロパティの値として指定しておきます。
// EC2インスタンスを作成する const ec2Instance = new Instance(this, 'EC2Instance', { vpc: vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, securityGroup: ec2Sg, instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MICRO), machineImage: new AmazonLinuxImage({ generation: AmazonLinuxGeneration.AMAZON_LINUX_2023, }), userData: userData, });
以上を実行することでEC2インスタンスにMariaDBとPostgreSQLがインストールされています。
確認
ユーザーデータの実行結果は、/var/log/cloud-init-output.log
に出力されます。確認してみると、無事dnfコマンドが実行されていることが確認できます。
コマンドも無事インストールされていることが確認できました。
考察
プライベートサブネットに配置したAmazon Linux 2023に対してインターネットに接続しないままパッケージのインストールすることを実装しました。NatGatewayは地味にお金がかかるサービスなので、必要なければ作らない方が良いかなと考えています。
パッケージのインストールのために今回はユーザーデータを使用しました。ユーザーデータ内の処理が失敗してもCDK自身の処理は正常終了するので、何らかの形で確認する必要はあります。