0
0

More than 3 years have passed since last update.

AWS CloudFormation EC2起動時にEFSをマウントする

Last updated at Posted at 2021-03-27

EFSをマウントするには

EC2のユーザーデータを使うことで、起動時にコマンドを実行することができます。今回はマウントコマンドを実行します。

主に以下の公式ドキュメントを参考にしましたが、今回書いた記事では起動設定をテンプレートには含めません。

必要なリソース

  • VPC
  • パブリックサブネット(プライベートサブネットでも同じ)
  • インターネットゲートウェイ
  • ルートテーブル
  • EC2
  • EFS
  • セキュリティグループ

これらをCloudFormationで作成します。その際、以下の設定もリソースとしてテンプレートに含めることになります。

  • ルートテーブルにサブネットを関連付ける
  • ルートテーブルをVPCにアタッチする
  • マウントターゲットを設定する

※インターネットゲートウェイ、ルートテーブル、セキュリティグループの3点は必須ではありません。これらはマウントできているかどうかをEC2にログインして確かめるためだけに使います。

テンプレート

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "VPC": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.0.0.0/16",
                "EnableDnsHostnames": true,
                "EnableDnsSupport": true
            }
        },
        "Subnet": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "CidrBlock": "10.0.0.0/24",
                "AvailabilityZone": "ap-northeast-1c",
                "VpcId": {
                    "Ref": "VPC"
                }
            }
        },
        "Instance": {
            "Type": "AWS::EC2::Instance",
            "DependsOn": "MountTarget",
            "Properties": {
                "KeyName": "private",
                "ImageId": "ami-0bc8ae3ec8e338cbc",
                "InstanceType": "t2.micro",
                "AvailabilityZone": "ap-northeast-1c",
                "NetworkInterfaces": [
                    {
                        "AssociatePublicIpAddress": true,
                        "DeviceIndex": "0",
                        "GroupSet": [
                            {
                                "Ref": "SecurityGroup"
                            },
                            {
                                "Fn::GetAtt": [
                                    "VPC",
                                    "DefaultSecurityGroup"
                                ]
                            }
                        ],
                        "SubnetId": {
                            "Ref": "Subnet"
                        }
                    }
                ],
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "#!/bin/bash\n",
                                "sudo mkdir /mnt/efs\n",
                                {
                                    "Fn::Sub": "sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /mnt/efs"
                                }
                            ]
                        ]
                    }
                }
            }
        },
        "SecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "CloufdFormation test",
                "SecurityGroupEgress": [
                    {
                        "IpProtocol": "-1",
                        "FromPort": "-1",
                        "ToPort": "-1",
                        "CidrIp": "0.0.0.0/0"
                    }
                ],
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": "22",
                        "ToPort": "22",
                        "CidrIp": "0.0.0.0/0"
                    }
                ],
                "VpcId": {
                    "Ref": "VPC"
                }
            }
        },
        "FileSystem": {
            "Type": "AWS::EFS::FileSystem",
            "Properties": {
                "Encrypted": true,
                "KmsKeyId": "arn:aws:kms:ap-northeast-1:012345678912:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            }
        },
        "MountTarget": {
            "Type": "AWS::EFS::MountTarget",
            "Properties": {
                "FileSystemId": {
                    "Ref": "FileSystem"
                },
                "SubnetId": {
                    "Ref": "Subnet"
                },
                "SecurityGroups": [
                    {
                        "Ref": "SecurityGroup"
                    },
                    {
                        "Fn::GetAtt": [
                            "VPC",
                            "DefaultSecurityGroup"
                        ]
                    }
                ]
            }
        },
        "Route": {
            "Type": "AWS::EC2::Route",
            "Properties": {
                "RouteTableId": {
                    "Ref": "RouteTable"
                },
                "DestinationCidrBlock": "0.0.0.0/0",
                "GatewayId": {
                    "Ref": "InternetGateway"
                }
            }
        },
        "RouteTable": {
            "Type": "AWS::EC2::RouteTable",
            "Properties": {
                "VpcId": {
                    "Ref": "VPC"
                }
            }
        },
        "InternetGateway": {
            "Type": "AWS::EC2::InternetGateway",
            "Properties": {}
        },
        "VPCGatewayAttachment": {
            "Type": "AWS::EC2::VPCGatewayAttachment",
            "Properties": {
                "InternetGatewayId": {
                    "Ref": "InternetGateway"
                },
                "VpcId": {
                    "Ref": "VPC"
                }
            }
        },
        "SubnetRouteTableAssociation": {
            "Type": "AWS::EC2::SubnetRouteTableAssociation",
            "Properties": {
                "RouteTableId": {
                    "Ref": "RouteTable"
                },
                "SubnetId": {
                    "Ref": "Subnet"
                }
            }
        }
    }
}

解説

Ref

リソースのIDを参照するときなどに使います。例えば、ルートテーブルをどのVPCにアタッチするか決めるときに、VPCのIDを参照します。その際、以下のように書くことで作成するVPCのIDを参照することができます。

"RouteTable": {
    "Type": "AWS::EC2::RouteTable",
    "Properties": {
        "VpcId": {
            "Ref": "VPC"
        }
    }
}

DependsON

EC2マウントターゲットの作成は、EC2の作成よりも遅いです。このコードを記述したリソースは、DependsOnで指定したリソースの作成後に作成されます。

"DependsOn": "MountTarget"

Fn::base64

ユーザーデータを使うときに必要です。

Fn::Join

文字列の結合に使います。リストのインデックス0には、区切り文字を指定します。インデックス1には、結合したい文字列のリストを指定します。

{ 
  "Fn::Join": 
      [
        "", ["pwd\n", "ls"]
      ]
}

Fn::Sub

変数に格納した値を展開できます。${AWS::Region}は定義せずともリージョンの値が展開されます。

{
  "Fn::Sub": "sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ${FileSystem}.efs.${AWS::Region}.amazonaws.com:/ /mnt/efs"
}

注意点

EC2インスタンスのセキュリティグループとサブネットIDは、Properties の中の NetworkInterfacesの中で設定します。

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0