CloudFormationでSSMパラメータストアを使用してみた。

2022-07-29

こんにちは、0371です。
CloudFormation内で、パラメータストアを使用してみました。
これを行うことで、動的な値を有する変数の管理をAWSに委譲することができます。

parameterstoreを活用するメリット

まずはparameterstoreを使用しない

parameterstoreを使用しないVPC、EC2、RDSの構成を作成しましょう。
サブネットは、パブリック1、プライベート2の構成です。
EC2にはセッションマネージャーで接続し、RDSにはEC2を介して接続しにいきます。

テンプレートの作成にあたって、以下のリポジトリを参考にさせていただいております。
>okubo-t / aws-cloudformation

まずは、VPCの作成です。

parameterstore-vpc.yml


AWSTemplateFormatVersion: "2010-09-09"

Description: Template generated by rain

# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: "Project Name Prefix and Environment"
        Parameters:
          - ProjectName
          - Env

# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
  ProjectName:
    Type: String
    Default: project
    Description: Enter Project Name. defailt is project.

  Env:
    Type: String
    Default: common
    AllowedValues:
      - common
      - prd
      - stg
      - dev
    Description: Enter common, prd, stg, dev. default is common.

# ------------------------------------------------------------#
# Mappings
# ------------------------------------------------------------#
Mappings:
  Environments:
    common:
      "VPCCIDR": "10.1.0.0/16"
      "PublicSubnetACIDR": "10.1.10.0/24"
      "PrivateSubnetACIDR": "10.1.50.0/24"
      "PrivateSubnetCCIDR": "10.1.60.0/24"
    prd:
      "VPCCIDR": "10.2.0.0/16"
      "PublicSubnetACIDR": "10.2.10.0/24"
      "PrivateSubnetACIDR": "10.2.50.0/24"
      "PrivateSubnetCCIDR": "10.2.60.0/24"
    stg:
      "VPCCIDR": "10.3.0.0/16"
      "PublicSubnetACIDR": "10.3.10.0/24"
      "PrivateSubnetACIDR": "10.3.50.0/24"
      "PrivateSubnetCCIDR": "10.3.60.0/24"
    dev:
      "VPCCIDR": "10.4.0.0/16"
      "PublicSubnetACIDR": "10.4.10.0/24"
      "PrivateSubnetACIDR": "10.4.50.0/24"
      "PrivateSubnetCCIDR": "10.4.60.0/24"

# ------------------------------------------------------------#
# Conditions
# ------------------------------------------------------------#
Conditions:
  IsApNorthEast1or3:
    !Or [
      !Equals [!Ref AWS::Region, "ap-northeast-1"],
      !Equals [!Ref AWS::Region, "ap-northeast-3"],
    ]

# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
  InternetGateway:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-igw"

  VPC:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !FindInMap [Environments, !Ref "Env", VPCCIDR]
      EnableDnsHostnames: true 
      EnableDnsSupport: true 
      InstanceTenancy: default 
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-vpc"

  VPCGatewayAttachment:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway 
      VpcId: !Ref VPC

  PublicRouteA:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: "0.0.0.0/0" 
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref PublicRouteTableA

  PublicRouteTableA:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::RouteTable
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-PublicRouteTable-1a"
      VpcId: !Ref VPC

  PrivateRouteTableA:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::RouteTable
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-PrivateRouteTable-1a"
      VpcId: !Ref VPC

  PrivateRouteTableC:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::RouteTable
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-PrivateRouteTable-1c"
      VpcId: !Ref VPC

  PublicSubnetA:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 0
        - !GetAZs
          Ref: AWS::Region 
      CidrBlock: !FindInMap [Environments, !Ref "Env", PublicSubnetACIDR]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-Public-Subnet-1a"
      VpcId: !Ref VPC

  PrivateSubnetA:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 0
        - !GetAZs
          Ref: AWS::Region 
      CidrBlock: !FindInMap [Environments, !Ref "Env", PrivateSubnetACIDR]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-Private-Subnet-1a"
      VpcId: !Ref VPC

  PrivateSubnetC:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select
        - 1
        - !GetAZs
          Ref: AWS::Region 
      CidrBlock: !FindInMap [Environments, !Ref "Env", PrivateSubnetCCIDR]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-${Env}-Private-Subnet-1c"
      VpcId: !Ref VPC

  PublicSubnetRouteTableAAssociation:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTableA
      SubnetId: !Ref PublicSubnetA

  PrivateSubnetRouteTableAAssociation:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTableA
      SubnetId: !Ref PrivateSubnetA

  PrivateSubnetRouteTableCAssociation:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTableC
      SubnetId: !Ref PrivateSubnetC

  EC2SecurityGroup:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::SecurityGroup"
    Properties: 
      VpcId: !Ref VPC
      GroupName: !Sub "${ProjectName}-ec2-sg"
      GroupDescription: "-"
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-ec2-sg"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 0.0.0.0/0

  RDSSecurityGroup:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupName: !Sub "${ProjectName}-rds-sg"
      GroupDescription: "-"
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-rds-sg"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: !FindInMap [Environments, !Ref "Env", VPCCIDR]

  DBSubnetGroup: 
    Condition: IsApNorthEast1or3
    Type: "AWS::RDS::DBSubnetGroup"
    Properties: 
      DBSubnetGroupName: !Sub "${ProjectName}-${Env}-rds-subnet"
      DBSubnetGroupDescription: "-"
      SubnetIds: 
        - !GetAtt PrivateSubnetA.SubnetId
        - !GetAtt PrivateSubnetC.SubnetId

  EC2EndpointSG:
    Condition: IsApNorthEast1or3 
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Bastion Endpoint Security Group"
      VpcId: !GetAtt VPC.VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !Ref EC2SecurityGroup
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-endpoint-bastion-sg"

  SSMVPCEndpoint:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::VPCEndpoint"
    Properties: 
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssm'
      VpcId: !GetAtt VPC.VpcId
      SubnetIds: 
        - Fn::ImportValue: !Sub "${ProjectName}-${Env}-PrivateSubnetASubnetId"
      SecurityGroupIds:
        - !Ref EC2EndpointSG
  
  SSMMessagesVPCEndpoint:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::VPCEndpoint"
    Properties: 
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ssmmessages'
      VpcId: !GetAtt VPC.VpcId
      SubnetIds: 
        - Fn::ImportValue: !Sub "${ProjectName}-${Env}-PrivateSubnetASubnetId"
      SecurityGroupIds:
        - !Ref EC2EndpointSG

  EC2MessagesVPCEndpoint:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::VPCEndpoint"
    Properties: 
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ec2messages'
      VpcId: !GetAtt VPC.VpcId
      SubnetIds: 
        - Fn::ImportValue: !Sub "${ProjectName}-${Env}-PrivateSubnetASubnetId"
      SecurityGroupIds:
        - !Ref EC2EndpointSG

# ------------------------------------------------------------#
# Outputs
# ------------------------------------------------------------#
Outputs:
  PublicSubnetAAvailabilityZone:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PublicSubnetA.AvailabilityZone
    Export:
      Name: !Sub "${ProjectName}-${Env}-PublicSubnetAAvailabilityZone"

  PublicSubnetAVpcId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PublicSubnetA.VpcId
    Export:
      Name: !Sub "${ProjectName}-${Env}-PublicSubnetAVpcId"

  PublicSubnetASubnetId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PublicSubnetA.SubnetId
    Export:
      Name: !Sub "${ProjectName}-${Env}-PublicSubnetASubnetId"

  PrivateSubnetAAvailabilityZone:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PrivateSubnetA.AvailabilityZone
    Export:
      Name: !Sub "${ProjectName}-${Env}-PrivateSubnetAAvailabilityZone"

  PrivateSubnetAVpcId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PrivateSubnetA.VpcId
    Export:
      Name: !Sub "${ProjectName}-${Env}-PrivateSubnetAVpcId"

  PrivateSubnetASubnetId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt PrivateSubnetA.SubnetId
    Export:
      Name: !Sub "${ProjectName}-${Env}-PrivateSubnetASubnetId"

  VPCId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt VPC.VpcId
    Export:
      Name: !Sub "${ProjectName}-${Env}-VpcId"

  VPCCidrBlock:
    Condition: IsApNorthEast1or3
    Value: !GetAtt VPC.CidrBlock
    Export:
      Name: !Sub "${ProjectName}-${Env}-VPCCidrBlock"

  EC2SecurityGroupGroupId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt EC2SecurityGroup.GroupId
    Export:
      Name: !Sub "${ProjectName}-${Env}-EC2SecurityGroupGroupId"

  RDSSecurityGroupGroupId:
    Condition: IsApNorthEast1or3
    Value: !GetAtt RDSSecurityGroup.GroupId
    Export:
      Name: !Sub "${ProjectName}-${Env}-RDSSecurityGroupGroupId"

つぎに、EC2、RDSです。

parameterstore-ec2-rds.yml

AWSTemplateFormatVersion: "2010-09-09"

Description: Template generated by rain

# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: "Project Name Prefix and Environment"
        Parameters:
          - ProjectName
          - Env
      - 
        Label:
          default: "EC2Instance Configuration"
        Parameters:
          # - KeyPairName
          - EC2InstanceAMI
          - EC2InstanceInstanceType
          - EC2InstanceVolumeType
          - EC2InstanceVolumeSize
      - 
        Label:
          default: "RDS Configuration"
        Parameters:
          - DBInstanceName
          - MySQLMajorVersion
          - MySQLMinorVersion
          - DBInstanceClass
          - DBInstanceStorageSize
          - DBInstanceStorageType
          - DBName
          - DBMasterUserName
          - DBPassword
          - MultiAZ
    ParameterLabels:
      # KeyPairName:
      #   default: "KeyPairName"
      EC2InstanceAMI:
        default: "EC2 AMI"
      EC2InstanceInstanceType:
        default: "EC2 InstanceType"
      EC2InstanceVolumeType:
        default: "EC2 VolumeType"
      EC2InstanceVolumeSize:
        default: "EC2 VolumeSize"
      DBInstanceName:
        default: "DBInstanceName"
      MySQLMajorVersion:
        default: "MySQLMajorVersion"
      MySQLMinorVersion:
        default: "MySQLMinorVersion"
      DBInstanceClass:
        default: "DBInstanceClass"
      DBInstanceStorageSize:
        default: "DBInstanceStorageSize"
      DBInstanceStorageType:
        default: "DBInstanceStorageType"
      DBName:
        default: "DBName"
      DBMasterUserName:
        default: "DBUserName"
      DBPassword:
        default: "DBPassword"
      MultiAZ:
        default: "MultiAZ"

# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
  ProjectName:
    Type: String
    Default: project
    Description: Enter Project Name. defailt is project.

  Env:
    Type: String
    Default: common
    AllowedValues:
      - common
      - prd
      - stg
      - dev
    Description: Enter common, prd, stg, dev. default is common.

  EC2InstanceAMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"

  EC2InstanceInstanceType:
    Type: String
    Default: "t2.micro"

  EC2InstanceVolumeType:
    Type: String
    Default: "gp2"

  EC2InstanceVolumeSize:
    Type: String
    Default: "30"

  DBInstanceName:
    Type: String
    Default: "rds"

  MySQLMajorVersion:
    Type: String
    Default: "8.0"
    AllowedValues: [ "5.7", "8.0" ]

  MySQLMinorVersion:
    Type: String
    Default: "25"
    AllowedValues: [ "22", "25" ]

  DBInstanceClass:
    Type: String
    Default: "db.m4.large" 

  DBInstanceStorageSize:
    Type: String
    Default: "30"

  DBInstanceStorageType:
    Type: String
    Default: "gp2"

  DBName:
    Type: String
    Default: "db"

  DBMasterUserName:
    Type: String
    Default: "dbuser"
    NoEcho: true
    MinLength: 1
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."

  DBPassword: 
    Default: "dbpassword"
    NoEcho: true
    Type: String
    MinLength: 8
    MaxLength: 41
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: "must contain only alphanumeric characters."
  
  MultiAZ: 
    Default: "false"
    Type: String
    AllowedValues: [ "true", "false" ]

# ------------------------------------------------------------#
# Mappings
# ------------------------------------------------------------#

# ------------------------------------------------------------#
# Conditions
# ------------------------------------------------------------#
Conditions:
  IsApNorthEast1or3:
    !Or [
      !Equals [!Ref AWS::Region, "ap-northeast-1"],
      !Equals [!Ref AWS::Region, "ap-northeast-3"],
    ]

# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
  EC2IAMRole: 
    Condition: IsApNorthEast1or3
    Type: "AWS::IAM::Role"
    Properties: 
      RoleName: !Sub "${ProjectName}-${Env}-ec2-role" 
      AssumeRolePolicyDocument: 
        Version: "2012-10-17"
        Statement: 
          - Effect: Allow
            Principal: 
              Service: 
                - "ec2.amazonaws.com"
            Action: 
              - "sts:AssumeRole"
      Path: "/"
      ManagedPolicyArns: 
        - "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
        - "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"

  EC2InstanceProfile: 
    Condition: IsApNorthEast1or3
    Type: "AWS::IAM::InstanceProfile"
    Properties: 
      Path: "/"
      Roles: 
        - Ref: EC2IAMRole
      InstanceProfileName: !Sub "${ProjectName}-${Env}-ec2-profile"

  EC2Instance:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::Instance"
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-ec2"
      ImageId: !Ref EC2InstanceAMI
      InstanceType: !Ref EC2InstanceInstanceType
      # KeyName: !Ref KeyPairName
      IamInstanceProfile: !Ref EC2InstanceProfile
      DisableApiTermination: false
      EbsOptimized: false
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            DeleteOnTermination: true
            VolumeType: !Ref EC2InstanceVolumeType
            VolumeSize: !Ref EC2InstanceVolumeSize
      SecurityGroupIds:
        -  Fn::ImportValue: !Sub "${ProjectName}-${Env}-EC2SecurityGroupGroupId"
      SubnetId: 
        Fn::ImportValue: !Sub "${ProjectName}-${Env}-PublicSubnetASubnetId"
      UserData: !Base64 | 
        #! /bin/bash
        sudo yum update -y  
        sudo yum install -y mysql

  ElasticIP:
    Condition: IsApNorthEast1or3
    Type: "AWS::EC2::EIP"
    Properties:
      Domain: vpc

  ElasticIPAssociate:
    Condition: IsApNorthEast1or3
    Type: AWS::EC2::EIPAssociation
    Properties: 
      AllocationId: !GetAtt ElasticIP.AllocationId
      InstanceId: !Ref EC2Instance

  DBInstance: 
    Condition: IsApNorthEast1or3
    Type: "AWS::RDS::DBInstance"
    Properties: 
      DBInstanceIdentifier: !Sub "${ProjectName}-${Env}-rds"
      Engine: MySQL
      EngineVersion: !Sub "${MySQLMajorVersion}.${MySQLMinorVersion}"
      DBInstanceClass: !Ref DBInstanceClass
      AllocatedStorage: !Ref DBInstanceStorageSize
      StorageType: !Ref DBInstanceStorageType
      DBName: !Ref DBName
      MasterUsername: !Ref DBMasterUserName
      MasterUserPassword: !Ref DBPassword
      DBSubnetGroupName: !Sub "${ProjectName}-${Env}-rds-subnet"
      PubliclyAccessible: false
      MultiAZ: !Ref MultiAZ
      PreferredBackupWindow: "18:00-18:30"
      PreferredMaintenanceWindow: "sat:19:00-sat:19:30"
      AutoMinorVersionUpgrade: false
      DBParameterGroupName: !Ref DBParameterGroup
      VPCSecurityGroups:
        - Fn::ImportValue: !Sub "${ProjectName}-${Env}-EC2SecurityGroupGroupId"
      CopyTagsToSnapshot: true
      BackupRetentionPeriod: 7
      Tags: 
        - Key: "Name"
          Value: !Ref DBInstanceName
    DeletionPolicy: "Delete"

  DBParameterGroup:
    Condition: IsApNorthEast1or3
    Type: "AWS::RDS::DBParameterGroup"
    Properties:
      Family: !Sub "MySQL${MySQLMajorVersion}"
      Description: !Sub "${ProjectName}-${Env}-rds-parm"

テンプレートは以上です。

テンプレートの実行、接続確認

では、テンプレートを実行します。
マネジメントコンソールからGUIで実行しても良いですが、自分はrainを使用します。

❯ rain deploy parameterstore-vpc.yml -p cli -y
❯ rain deploy parameterstore-ec2-rds.yml -p cli -y
  1. parameterstore-vpc.yml
  2. parameterstore-ec2-rds.yml

の順番で実行しましょう。

実行が完了したら、RDSのエンドポイントURLをメモします。
次に、作成したEC2インスタンスにセッションマネージャーで接続しにいきます。
そこで、以下のコマンドを実行し、mysqlに接続できればOKです。

sh-4.2$ mysql -u dbuser -p -h メモしたRDSのエンドポイントURL
Enter password: dbpassword

MySQL [(none)]>

ソースコードの追加、変更

それでは、parameterstoreを使用するために、テンプレートを編集していきます。

今回は、簡単にRDSのログインユーザー名をparameterstoreに格納し、それを使用しようと思います。

新しくテンプレートを作成します。

parameterstore-parm.yml

AWSTemplateFormatVersion: "2010-09-09"

Description: Template generated by rain

# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - 
        Label:
          default: "Project Name Prefix and Environment"
        Parameters:
          - ProjectName
          - Env
          - RDSMasterUsername

# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
Parameters:
  ProjectName:
    Type: String
    Default: project
    Description: Enter Project Name. defailt is project.

  Env:
    Type: String
    Default: common
    AllowedValues:
      - common
      - prd
      - stg
      - dev
    Description: Enter common, prd, stg, dev. default is common.

  RDSMasterUsername:
    Default: dbuser
    Type: String
    NoEcho: true
    MinLength: 1
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."

# ------------------------------------------------------------#
# Resources
# ------------------------------------------------------------#
Resources:
  SSMParameterForRDSMasterUsername:
    Type: "AWS::SSM::Parameter"
    Properties:
      Name: "RDSMasterUsername"
      Type: "String"
      Value: !Ref RDSMasterUsername
      Description: "MasterUsername for RDS"
      Tags:
        Name: !Sub "${ProjectName}-${Env}-RDSMasterUsername"

次に、parameterstore-ec2-rds.ymlの編集を行います。

parameterstore-ec2-rds.yml

-      MasterUsername: !Ref DBMasterUserName
+      MasterUsername: "{{resolve:ssm:RDSMasterUsername}}"

再度テンプレートの実行、接続確認

では、テンプレートの実行、更新、接続確認をします。

❯ rain deploy parameterstore-parm.yml -p cli -y
❯ rain deploy parameterstore-ec2-rds.yml -p cli -y

EC2インスタンスにセッションマネージャーで接続し、またmysqlへのアクセスを行います。

sh-4.2$ mysql -u dbuser -p -h メモしたRDSのエンドポイントURL
Enter password: dbpassword

MySQL [(none)]>

無事に接続できました。

後片付け

後片付けもします。 VPCはセキュリティグループを手動で削除した後に削除実行してください。

❯ rain ls -p cli
❯ rain rm parameterstore-ec2-rds -p cli -y
❯ rain rm parameterstore-vpc -p cli -y
❯ rain rm parameterstore-parm -p cli -y
❯ rain ls -p cli

参考サイト

okubo-t / aws-cloudformation

今日の一言

SecretManagerも使ってみたい