AWS Severless IoT 10 – RDS+VPC

AWS Severless IoT에 대해 알아봅니다.

작성자

홍세민

홍세민

MarcusHong

RDS + VPC

채팅앱에서 채팅 메세지 이외의 user 정보가 만약 여러 관계가 필요한 데이터가 필요하다면 RDS를 사용하는 것이 좋다. Cloudformation으로 RDS를 생성하고 VPC를 구성해서 보안을 강화해보자.

주요 기능

  • Mysql: RDS를 사용함.
  • SNS Topic: CPU 사용량이 80%가 넘어가면 메일 알림
  • Security Group을 설정해서 사무실에서 쓰는 ip만 접근을 허용한다.
  • NetworkAcl, Route Table, Route Table Association, PrivateSubnet, DBSubnetGroup 어느 것 하나라도 연결되지 않으면 접속되지 않는다.
  • PrivateSubnet은 최소 2개이상 만들어야 한다.

Cloudformation

Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      EnableDnsSupport: true
      EnableDnsHostnames: true
      CidrBlock: 172.34.0.0/16

  VPCSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Security Group for our private VPC
      SecurityGroupEgress: []
      SecurityGroupIngress:
        - CidrIp: {office ip}/32
          FromPort: 3306
          IpProtocol: TCP
          ToPort: 3306
        - CidrIp: 172.34.0.0/16
          FromPort: 3306
          IpProtocol: TCP
          ToPort: 3306
      VpcId:
        Ref: VPC

  NetworkAcl:
    Type: 'AWS::EC2::NetworkAcl'
    Properties:
      VpcId:
        Ref: VPC

  InboundNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId:
        Ref: NetworkAcl
      RuleNumber: 100
      Protocol: -1
      RuleAction: allow
      Egress: false
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 0
        To: 65535

  OutboundNetworkAclEntry:
    Type: 'AWS::EC2::NetworkAclEntry'
    Properties:
      NetworkAclId:
        Ref: NetworkAcl
      RuleNumber: 100
      Protocol: -1
      RuleAction: allow
      Egress: true
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 0
        To: 65535

  PrivateSubnetA:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: ap-northeast-2a
      CidrBlock: 172.34.128.0/24
      MapPublicIpOnLaunch: true

  PrivateSubnetB:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: ap-northeast-2c
      CidrBlock: 172.34.129.0/24
      MapPublicIpOnLaunch: true

  PrivateRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId:
        Ref: VPC

  PrivateSubnetRouteTableAssociationA:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId:
        Ref: PrivateSubnetA
      RouteTableId:
        Ref: PrivateRouteTable

  PrivateSubnetRouteTableAssociationB:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId:
        Ref: PrivateSubnetB
      RouteTableId:
        Ref: PrivateRouteTable

  PrivateSubnetNetworkAclAssociationA:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId:
        Ref: PrivateSubnetA
      NetworkAclId:
        Ref: NetworkAcl

  PrivateSubnetNetworkAclAssociationB:
    Type: 'AWS::EC2::SubnetNetworkAclAssociation'
    Properties:
      SubnetId:
        Ref: PrivateSubnetB
      NetworkAclId:
        Ref: NetworkAcl

  StackAlarmTopic:
    Type: 'AWS::SNS::Topic'
    Properties:
      DisplayName: Stack Alarm Topic

  DatabaseSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      DBSubnetGroupDescription: PrivateSubnetGroup
      SubnetIds:
        - Ref: PrivateSubnetA
        - Ref: PrivateSubnetB

  DatabasePrimaryInstance:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      Engine: mysql
      EngineVersion: 5.7.19
      AllocatedStorage: 20
      StorageType: gp2
      DBName: sample
      DBInstanceClass: db.t2.micro
      DBSubnetGroupName:
        Ref: DatabaseSubnetGroup
      DBParameterGroupName:
        Ref: RDSDBParameterGroup
      MasterUsername: sampleDev
      MasterUserPassword: {password}
      BackupRetentionPeriod: 1
      PreferredBackupWindow: '17:00-18:00'
      PreferredMaintenanceWindow: 'mon:18:00-mon:19:00'
      MonitoringInterval: 60
      MonitoringRoleArn:
        'Fn::GetAtt':
          - DatabaseWatchRole
          - Arn
      VPCSecurityGroups:
        - Ref: VPCSecurityGroup
      PubliclyAccessible: true

  DatabasePrimaryCPUAlarm:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      AlarmDescription: Primary database CPU utilization is over 80%.
      Namespace: AWS/RDS
      MetricName: CPUUtilization
      Unit: Percent
      Statistic: Average
      Period: 300
      EvaluationPeriods: 2
      Threshold: 80
      ComparisonOperator: GreaterThanOrEqualToThreshold
      Dimensions:
        - Name: DBInstanceIdentifier
          Value:
            Ref: DatabasePrimaryInstance
      AlarmActions:
        - Ref: StackAlarmTopic
      InsufficientDataActions:
        - Ref: StackAlarmTopic

  RDSDBParameterGroup:
    Type: 'AWS::RDS::DBParameterGroup'
    Properties:
      Description: CloudFormation Aurora Parameter Group
      Family: mysql5.7
      Parameters:
        sql_mode: ANSI
        max_connections: 6000

  DatabaseWatchRole:
    Type: 'AWS::IAM::Role'
    Properties:
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: monitoring.rds.amazonaws.com
            Action: 'sts:AssumeRole'

추가사항

  • 네트워크 기반 지식이 충분하지 않다면, route table, subnet에서 많이 헤멜 수 있다.
  • 네트워크 지식이 충분하지 않다면, AWS Console에서 VPC Wizard로도 생성할 수 있다.
  • PrivateRouteTable은 Lambda 함수의 인터넷 접속을 위한 부분으로 Lambda - Internet Access 에서 설명한다.

Tags : aws 

comments powered by Disqus