「監視編 サーバーのモニタリングの基本を学ぼう」のハンズオンした

## 概要
AWSの監視を体験しました

![スクリーンショット 2024-04-07 13.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747730/1dd48902-6823-a0f1-1cab-497948537db3.png)


https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-monitoring-2022-reg-event.html

## CloudFormation
※ セミナーの内容と全て一致していないので、ご注意ください

```yml
AWSTemplateFormatVersion: "2010-09-09"
Description: AWS Hands-on for Beginners monitoing-1 template

Parameters:
  EC2InstanceType:
    Type: String
    Default: t2.micro
  EC2AMI:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2  
  RDSInstanceType:
    Type: String
    Default: db.m5d.large
  DBUser:
    Type: String
    Default: dbmaster
  DBPassword:
    Type: String
    Default: H&ppyHands0n
    NoEcho: true

Resources:
  CFnVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      InstanceTenancy: default
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-vpc

  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [0, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [1, !GetAZs ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.2.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [0, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.3.0/24
      VpcId: !Ref CFnVPC
      AvailabilityZone: !Select [1, !GetAZs ]
      Tags:
        - Key: Name
          Value: PrivateSubnet2

  CFnVPCIGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-igw

  CFnVPCIGWAttach:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref CFnVPCIGW
      VpcId: !Ref CFnVPC

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref CFnVPC
      Tags:
        - Key: Name
          Value: Public Route

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref CFnVPCIGW

  PublicSubnet1Assoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2Assoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  EC2WebServer01:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-WebServer01
      ImageId: !Ref EC2AMI
      InstanceType: !Ref EC2InstanceType
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: '0'
          SubnetId: !Ref PublicSubnet1
          GroupSet:
            - !Ref SecurityGroupWebServer
      UserData: !Base64 | 
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service

        wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm -P /tmp/
        sudo rpm -U /tmp/amazon-cloudwatch-agent.rpm
        mv /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/default /home/ec2-user/
        wget https://raw.githubusercontent.com/nikuyoshi/aws-monitoring-hands-on-1/master/amazon-cloudwatch-agent.json -P /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/
        sudo systemctl restart amazon-cloudwatch-agent
      IamInstanceProfile: !Ref IAMInstanceProfile
    DependsOn: IAMInstanceProfile
        
  EC2WebServer02:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-WebServer02
      ImageId: !Ref EC2AMI
      InstanceType: !Ref EC2InstanceType
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: '0'
          SubnetId: !Ref PublicSubnet2
          GroupSet:
            - !Ref SecurityGroupWebServer
      UserData: !Base64 | 
        #! /bin/bash
        yum update -y
        amazon-linux-extras install php7.2 -y
        yum -y install mysql httpd php-mbstring php-xml
        
        wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
        tar zxvf /tmp/latest-ja.tar.gz -C /tmp
        cp -r /tmp/wordpress/* /var/www/html/
        touch /var/www/html/.check_alive
        chown apache:apache -R /var/www/html
        
        systemctl enable httpd.service
        systemctl start httpd.service

        wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm -P /tmp/
        sudo rpm -U /tmp/amazon-cloudwatch-agent.rpm
        mv /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/default /home/ec2-user/
        wget https://raw.githubusercontent.com/nikuyoshi/aws-monitoring-hands-on-1/master/amazon-cloudwatch-agent.json -P /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/
        sudo systemctl restart amazon-cloudwatch-agent
      IamInstanceProfile: !Ref IAMInstanceProfile
    DependsOn: IAMInstanceProfile

  SecurityGroupWebServer:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      VpcId: !Ref CFnVPC
      GroupName: !Sub ${AWS::StackName}-WebServer
      GroupDescription: !Sub ${AWS::StackName}-WebServer
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-WebServer
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  Monitoring1EC2RoleforSSM:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: 'sts:AssumeRole'
          Effect: Allow
          Principal:
            Service: ec2.amazonaws.com
      Description: Allows EC2 instances to call AWS services on your behalf.
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM
      - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
      MaxSessionDuration: 3600
      Path: "/"
      RoleName: Monitoring1EC2RoleforSSM

  IAMInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles: [ !Ref Monitoring1EC2RoleforSSM ]
      Path: "/"

  FrontLB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub ${AWS::StackName}-elb
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      SecurityGroups: 
        - !Ref SecurityGroupLB

  FrontLBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref FrontLB
      Port: 80
      Protocol: HTTP 
      DefaultActions: 
        - Type: forward
          TargetGroupArn: !Ref FrontLBTargetGroup

  FrontLBTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub ${AWS::StackName}-tg
      VpcId: !Ref CFnVPC
      Port: 80
      Protocol: HTTP
      HealthCheckPath: /.check_alive
      Targets:
        - Id: !Ref EC2WebServer01
        - Id: !Ref EC2WebServer02

  SecurityGroupLB:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      VpcId: !Ref CFnVPC
      GroupName: !Sub ${AWS::StackName}-lb-security-group
      GroupDescription: !Sub ${AWS::StackName}-lb-security-group
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-lb-security-group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0

  DBInstance:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Delete
    Properties:
      DBInstanceIdentifier: !Sub ${AWS::StackName}-rds
      DBName: wordpress
      Engine: MySQL
      MasterUsername: !Ref DBUser
      MasterUserPassword: !Ref DBPassword
      DBInstanceClass: !Ref RDSInstanceType
      StorageType: gp2
      AllocatedStorage: '20'
      BackupRetentionPeriod: 0
      DBSubnetGroupName: !Ref DBSubnetGroup
      MultiAZ: true
      VPCSecurityGroups:
        - !Ref SecurityGroupDB

  DBSubnetGroup: 
    Type: AWS::RDS::DBSubnetGroup
    Properties: 
      DBSubnetGroupDescription: DB Subnet Group for Private Subnet
      SubnetIds: 
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2

  SecurityGroupDB:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      VpcId: !Ref CFnVPC
      GroupName: !Sub ${AWS::StackName}-MySQL
      GroupDescription: !Sub ${AWS::StackName}-MySQL
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-MySQL
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.0.0/16
  
  Alarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      AlarmActions: 
        - !Ref Monitoring1Topic
      Dimensions:
        - Name: path
          Value: /dev/shm
        - Name: InstanceId
          Value: !GetAtt EC2WebServer01.InstanceId
        - Name: ImageId
          Value: !Ref EC2AMI
        - Name: InstanceType
          Value: !Ref EC2InstanceType
        - Name: device
          Value: tmpfs
        - Name: fstype
          Value: tmpfs
      Statistic: Average
      MetricName: disk_used_percent
      Namespace: CWAgent
      Period: 900
      Threshold: 90
      Unit: Percent

  Monitoring1Topic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: monitoring-1-topic
  
  DiskUsagePercentSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: email
      TopicArn: !Ref Monitoring1Topic
      Endpoint: kyozasoze@instaddr.uk
  
  EventsRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern: !Sub |
        {
          "source": ["aws.ec2"],
          "detail-type": ["EC2 Instance State-change Notification"],
          "detail": {
            "state": ["stopped"]
          }
        }
      Targets: 
        - 
          Arn: !Ref Monitoring1Topic
          Id: Monitoring1Topic

  Dashboard:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardBody: !Sub 
          - |- 
            {
              "widgets": [
                {
                  "type":"metric",
                  "x":0,
                  "y":0,
                  "width":12,
                  "height":6,
                  "properties":{
                    "metrics":[
                      [
                        "CWAgent",
                        "disk_used_percent",
                        "path", 
                        "/dev/shm",
                        "InstanceType",
                        "t2.micro",
                        "ImageId",
                        "${ImageId}",
                        "InstanceId",
                        "${InstanceId1}",
                        "device",
                        "tmpfs",
                        "fstype",
                        "tmpfs" 
                      ],
                      [
                        "CWAgent",
                        "disk_used_percent",
                        "path", 
                        "/dev/shm",
                        "InstanceType",
                        "t2.micro",
                        "ImageId",
                        "${ImageId}",
                        "InstanceId",
                        "${InstanceId2}",
                        "device",
                        "tmpfs",
                        "fstype",
                        "tmpfs" 
                      ]
                    ],
                    "stat":"Average",
                    "region":"ap-northeast-1",
                    "liveData": false,
                    "legend": {
                        "position": "right"
                    }
                  }
                },
                {
                  "type":"text",
                  "x":0,
                  "y":7,
                  "width":3,
                  "height":3,
                  "properties":{
                      "markdown": "# WordPressの障害メモ    [button:primary:非常時ボタン](http://amazon.com)",
                      "background": "transparent"
                  }
                },
                {
                  "type": "log",
                  "x": 12,
                  "y": 24,
                  "width": 12,
                  "height": 6,
                  "properties": {
                      "region": "ap-northeast-1",
                      "title": "waordpress_access_log",
                      "query": "SOURCE 'wordpress_access_log' | fields @timestamp, @message | sort timestamp desc | limit 20",
                      "view": "table"
                  }
                }
              ]
            }
          - ImageId: !Ref EC2AMI
            InstanceId1: !GetAtt EC2WebServer01.InstanceId
            InstanceId2: !GetAtt EC2WebServer02.InstanceId

Outputs:
  VPCID:
    Description: VPC ID
    Value: !Ref CFnVPC

  PublicSubnet1:
    Description: PublicSubnet 1
    Value: !Ref PublicSubnet1

  PublicSubnet2:
    Description: PublicSubnet 2
    Value: !Ref PublicSubnet2

  PrivateSubnet1:
    Description: PrivateSubnet 1
    Value: !Ref PrivateSubnet1

  PrivateSubnet2:
    Description: PrivateSubnet 2
    Value: !Ref PrivateSubnet2

  EC2WebServer01:
    Value: !Ref EC2WebServer01

  EC2WebServer01DNS:
    Value: !GetAtt EC2WebServer01.PublicDnsName

  EC2WebServer02:
    Value: !Ref EC2WebServer02

  EC2WebServer02DNS:
    Value: !GetAtt EC2WebServer02.PublicDnsName

  FrontLBEndpoint:
    Value: !GetAtt FrontLB.DNSName

  RDSEndpointAddress:
    Value: !GetAtt DBInstance.Endpoint.Address

```