Help us understand the problem. What is going on with this article?

AWSでログ監視をなるべくansibleから設定する

More than 1 year has passed since last update.

AWSでログ監視をなるべくansibleから設定する

ゴール

アプリケーションのログをCloudWatchで監視し、アラームがあげられるようなec2サーバ環境のansibleによる自動構築

注意

いくつかわかったことと、わからないことがあり、わからないことが解決したら書き換えていきます。
必ずしも全てあっているわけではありません。

ansibleによるec2インスタンスの構築・立ち上げ

ansibleとは サーバ等を自動構築するための構成管理ツール

Ansilbe All Modulesを見ると、多くのaws設定モジュールがansibleには存在します。
コンソール、aws cliでできることが完全に網羅されていませんがこれらのモジュールを使うとansibleの中で構成変更とその結果を出力することができます。

aws cliで構築するやり方をAWS CLIで構築するCloudWatch Agentより参考としました。

ec2インスタンスの構築公開は後回しにします。

ansibleによるec2サーバの設定

ここではawsに構築されたec2インスタンスにパッケージ等インストールしてCloudWatchでサーバの監視ができる状態をansibleで作ります。

ec2は構築のたびにIPとか変わります。そのためansibleの静的設定ファイルにホストの指定ができません。そのためawsからそれを取得するEC2 External Inventoryというツールがあります。ここなどを参考にこれを導入しました。

まずは必要なパッケージのインストール

次のようなansibleの構成にて単純なパッケージの導入と起動とかを設定していきます。

.
├── hosts
│   ├── prod
│   └── stg
│       ├── ec2.ini
│       └── ec2.py
├── roles
│   └── packages
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
└── site.yml

導入したいパッケージ

次の2つが必要なパッケージだがAmazon Linux 2のAMIを選択してインスタンスを作っておいたらすでにインストール済みでした。

amazon-cloudwatch-agent
amazon-ssm-agent

インスタンスにログインし次を実行。

[ec2-user@ip-10-1-21-4 bin]$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
{
  "status": "stopped",
  "starttime": "",
  "version": "1.208036.0"
}
[ec2-user@ip-10-1-21-4 bin]$

加えてこちらのパッケージを導入。

collectd

collectdの設定方法を参考とさせていただきました。

collectdで集めた情報をCloudWatchから参照することができる。

aws cloudwatch ...

というcliもあるがcollectd等と連携することが推奨されているようだ。

次のようにcollectdの設定を変更して再起動する。

- name: collectd configuration
  lineinfile: >-
    dest='/etc/collectd.conf'
    state=present
    backrefs=yes
    regexp='{{ item.regexp }}'
    line='{{ item.line}}'
  with_items:
  - regexp: '^#?\s*LoadPlugin disk'
    line: 'LoadPlugin disk'
  - regexp: '^#?\s*LoadPlugin email'
    line: 'LoadPlugin email'
  register: conf
- debug: var=conf

- name: dependency service restart
  service:
    name: collectd
    state: restarted

CloudWatchに情報を送るIAMユーザを作成

次のポリシーをアタッチしたIAMユーザを作成

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "cloudwatch:PutMetricData",
            "Resource": "*"
        }
    ]
}

AWS Sytems Manager Sericesからコマンド実行のトラブルシューティング(原因不明)が発生。

CloudWatch エージェント設定ファイルを手動で作成または編集するを見て頑張って設定ファイルを作ってみる。

一度「Amazon Web Services パターン別構築・運用ガイド」を読んで実行していたのでP.414で生成されたファイルを元に変更している。

metrics

diskの計測方法(measurement)を変えている

    "metrics": {
    "append_dimensions": {
        "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
        "ImageId": "${aws:ImageId}",
        "InstanceId": "${aws:InstanceId}",
        "InstanceType": "${aws:InstanceType}"
    },
    "metrics_collected": {
        "collectd": {
        "metrics_aggregation_interval": 60
        },
        "cpu": {
        "measurement": [
            "cpu_usage_idle",
            "cpu_usage_iowait",
            "cpu_usage_user",
            "cpu_usage_system"
        ],
        "metrics_collection_interval": 60,
        "resources": [
            "*"
        ],
        "totalcpu": false
        },
        "disk": {
        "measurement": [
            "total",
            "used",
            "free",
            "used_percent",
            "inodes_free"
        ],
        "metrics_collection_interval": 60,
        "resources": [
            "*"
        ]
        },
        "diskio": {
        "measurement": [
            "io_time",
            "write_bytes",
            "read_bytes",
            "writes",
            "reads"
        ],
        "metrics_collection_interval": 60,
        "resources": [
            "*"
        ]
        },
        "mem": {
        "measurement": [
            "mem_used_percent"
        ],
        "metrics_collection_interval": 60
        },
        "netstat": {
        "measurement": [
            "tcp_established",
            "tcp_time_wait"
        ],
        "metrics_collection_interval": 60
        },
        "statsd": {
        "metrics_aggregation_interval": 60,
        "metrics_collection_interval": 10,
        "service_address": ":8125"
        },
        "swap": {
        "measurement": [
            "swap_used_percent"
        ],
        "metrics_collection_interval": 60
        }
    }

logs

ログはデフォルトでmessagesの監視がついていたがそれをコピーしてアプリケーションのログを監視できるようにした。

    "logs": {
    "logs_collected": {
        "files": {
        "collect_list": [
            {
            "file_path": "/var/log/messages",
            "log_group_name": "messages",
            "log_stream_name": "{instance_id}"
            },
            {
            "file_path": "/var/log/application.log",
            "log_group_name": "application",
            "log_stream_name": "{instance_id}"
            }
        ]
        }
    }
    },

agent

ウィザードを使って生成した元にはagentがなかったが、ログを見てみようと思いdebugを入れた。

    "agent": {
    "debug": true
    },
 $ aws ssm describe-instance-information --instance-information-filter-list key=PingStatus,valueSet=Online                                                                                                                    [17:48:26]
{
    "InstanceInformationList": [
        {
            "IsLatestVersion": false, 
            "ComputerName": "ip-x-x-x-x.us-west-2.compute.internal", 
            "PingStatus": "Online", 
            "InstanceId": "i-xxxx7cb53516b635e", 
            "IPAddress": "xx.xx.xx.xx", 
            "ResourceType": "EC2Instance", 
            "AgentVersion": "2.3.372.0", 
            "PlatformVersion": "2", 
            "PlatformName": "Amazon Linux", 
            "PlatformType": "Linux", 
            "LastPingDateTime": 1554108523.909
        }
    ]
}

設定ファイルを配布する

AWS CLIで構築するCloudWatch Agent
CloudWatch Agentの設定ファイルをパラメータストアにアップロード を参考に
AWS SYSTEM MANAGERのパラメータストア にアップロードすることにした。

ansibleにもaws_ssm_parameter_storeというパラメータストアの管理モジュールがありましたので、それを使います。
値は設定ファイルから設定しています。

  • aws.cloudwatchagent.name AmazonCloudWatch-linux
  • aws.cloudwatchagent.file 上記設定ファイルを別ファイルとしてパスを記載
- name: copy conf file SSM parameter store
  aws_ssm_parameter_store:
    region: "{{ aws.common.region }}"
    name: "{{ aws.cloudwatchagent.name }}"
    description: "{{ aws.cloudwatchagent.description }}"
    string_type: String
    value: "{{ lookup('file',aws.cloudwatchagent.file) }}"
  register: aws_ssm_parameter_store
- debug: var=aws_ssm_parameter_store

設定を反映する。

AWS CLIで構築するCloudWatch Agent
CloudWatch Agent設定 を参考にansibleを定義します。
モジュールは存在しなかったのでaws cliを実行することにしました。

ec2インスタンスはすでに構築されている前提で、まずはec2のインスタンスIDを取得します。
私の環境ではsystemというタグでいくつかグループを分けていたためフィルタに設定しています。各自の環境に読み替えてください。

- name: get ec2 instanceids
  ec2_instance_facts:
    region: "{{ aws.common.region }}"
    filters:
      "tag:system": "{{ aws.common.target }}"
  register: ec2_instance_facts
- debug: var=ec2_instance_facts

次に取得したインスタンスIDに対してコマンドを実行します。

- name: aws CloudWatch config
  command: >
    aws ssm send-command 
      --document-name "AmazonCloudWatch-ManageAgent" 
      --targets "Key=instanceids,Values='{{ item.instance_id }}'" 
      --parameters "action=configure, mode=ec2, optionalConfigurationSource=ssm, optionalConfigurationLocation=AmazonCloudWatch-linux, optionalRestart=yes" 
      --profile {{ aws.common.profile }}
      --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region "{{ aws.common.region }}"
  with_items: "{{ ec2_instance_facts.instances }}"

うまく実行できたら AWS コンソールからログインし、CloudWatchのメトリクスを確認します。
CWAgentにCloudWatchAgentの設定を行なったec2インスタンスが追加されていれば成功です。

.
├── hosts
│   ├── prod
│   └── stg
│       ├── ec2.ini
│       └── ec2.py
├── roles
│   ├── cloudwatch
│   │   ├── tasks
│   │   │   ├── main.yml
│   │   └── vars
│   │       ├── main.yml
│   ├── iam_role
│   │   └── tasks
│   │       └── main.yml
│   └── packages
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
└── site.yml
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away