Skip to content

shu130/terraform-study23

Repository files navigation

Terraform勉強-第23回:CloudWatchエージェント, SSMパラメータストアでログを CloudWatch Logs に送信する

githubリポジトリ:"https://github.com/shu130/terraform-study23"

テーマ:

  • EC2 オートスケーリンググループでApacheを導入し、CloudWatchエージェントを利用してアクセスログとエラーログを CloudWatch Logs に送信する環境を構築
  • ASG (Auto Scaling Group) を使用して EC2 インスタンスをスケーリングし、Web サーバの冗長性を確保
  • SSMパラメータストア を活用してCloudWatch エージェントの設定を共有、複数インスタンスへの一貫した設定配布

ディレクトリ

.
├── provider.tf
├── vpc.tf
├── iam.tf
├── autoscaling.tf
├── cloudwatch.tf
├── ssm.tf
├── scripts
│   └── fetch_cloudwatch_config.sh
├── variables.tf
├── terraform.tfvars
└── outputs.tf

概要図

概要図

コード作成と理解

1. IAM ロールとポリシーとインスタンスプロファイル

  • ASG用IAM ロールを作成
  • CloudWatch エージェントがCloudWatch Logs にログ送信できるように、CloudWatchAgentServerPolicy ポリシーを IAM ロールにアタッチ
  • EC2 インスタンスが SSM パラメータストアから設定情報を取得できるように、AmazonSSMReadOnlyAccess ポリシーもIAM ロールにアタッチ
  • 作成した IAM ロールを IAM インスタンスプロファイル として定義し、Auto Scaling Group (ASG) のインスタンスが起動時にこの IAM ロールを使用
# ./iam.tf

# IAMロールを作成
resource "aws_iam_role" "cloudwatch_agent_role" {
  name = "CloudWatchAgentRole"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action    = "sts:AssumeRole"
      Effect    = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
  })
}

# IAMロールに2つのポリシーをアタッチ:
## 1.cloudwatch-Logsへのログ送信用
resource "aws_iam_role_policy_attachment" "cloudwatch_logs" {
  role       = aws_iam_role.cloudwatch_agent_role.name
  policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}

## 2. SSMパラメータストア接続用
resource "aws_iam_role_policy_attachment" "ssm_access" {
  role       = aws_iam_role.cloudwatch_agent_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess"
}

# IAMロールをインスタンスプロファイルとして定義
resource "aws_iam_instance_profile" "cloudwatch_instance_profile" {
  name = "CloudWatchInstanceProfile"
  role = aws_iam_role.cloudwatch_agent_role.name
}

2. Auto Scaling Group(ASG)

  • IAM インスタンスプロファイルを通じて、ASG 内のすべての EC2 インスタンスが一貫して CloudWatch Logs へのアクセスと、SSM パラメータストアから設定を取得
  • EC2 インスタンスのスケールイン/スケールアウトを自動化
  • user_data スクリプトによりASG でインスタンスが起動する際に、Apache をインストールし、CloudWatch エージェントの設定ファイルを取得して、CloudWatch Logs にログを送信
#./autoscaling.tf

# 起動テンプレート作成
resource "aws_launch_template" "web_launch_template" {
  name_prefix = "${var.ec2_instance_name}-lt-"
  image_id      = var.ec2_ami
  instance_type = var.ec2_instance_type
  key_name      = var.ec2_key_pair
  
  # インスタンスプロファイルを適用
  iam_instance_profile {
    name = aws_iam_instance_profile.cloudwatch_instance_profile.name
  }

  network_interfaces {
    associate_public_ip_address = true
    security_groups = [aws_security_group.asg_sg.id]
  }

  # user_dataスクリプトを指定
  user_data = base64encode(templatefile("${path.module}/scripts/fetch_cloudwatch_config.sh", {}))

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name = "${var.ec2_instance_name}"
    }
  }
}

# オートスケール設定
resource "aws_autoscaling_group" "web_asg" {
  desired_capacity    = 2
  max_size            = 4
  min_size            = 2
  vpc_zone_identifier = aws_subnet.public_subnets[*].id
  launch_template {
    id      = aws_launch_template.web_launch_template.id
    version = "$Latest"
  }

  tag {
    key   = "Name"
    value = "${var.ec2_instance_name}"
    propagate_at_launch = true
  }
}

user_dataスクリプト(fetch_cloudwatch_config.sh)について:

  • 初回起動時に自動実行
  • インスタンス起動時にApacheとCloudWatchエージェントをインストール
  • SSMパラメータストアからCloudWatchエージェントの設定を取得
  • 動的にインスタンスIDを取得して設定に反映
# ./scripts/fetch_cloudwatch_config.sh

#!/bin/bash
# Apacheのインストールと起動
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd

# CloudWatchエージェントのインストール
yum install -y amazon-cloudwatch-agent
# jqのインストール
yum install -y jq

# SSMパラメータストアからCloudWatch設定情報を取得し、エージェント起動
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws ssm get-parameter --name "AmazonCloudWatch-ForwardProxy" --query "Parameter.Value" --output text --region "us-west-2" | \
  jq --arg id "$INSTANCE_ID" '.logs.logs_collected.files.collect_list[] |= (.log_stream_name = $id)' | \
  sudo tee /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json > /dev/null

/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

3. SSM パラメータストア

  • aws_ssm_parameter リソースで、CloudWatch エージェントの設定情報を保存
  • EC2インスタンスの起動スクリプト (fetch_cloudwatch_config.sh)によって、
    SSMから設定を取得し、jqでプレースホルダ {instance_id} を実際のインスタンスIDに置き換え
# CloudWatchエージェントの設定をSSMパラメータストアへ保存
resource "aws_ssm_parameter" "cloudwatch_config" {
  name  = "AmazonCloudWatch-ForwardProxy"
  type  = "String"
  value = jsonencode({
    logs = {
      logs_collected = {
        files = {
          collect_list = [
            {
              file_path        = "/var/log/messages"
              log_group_name   = "var-log-messages"
              log_stream_name  = "{instance_id}"
              timestamp_format = "%b %d %H:%M:%S"
            },
            {
              file_path        = "/var/log/httpd/access_log"
              log_group_name   = "HttpAccessLog"
              log_stream_name  = "{instance_id}"
              timestamp_format = "%b %d %H:%M:%S"
            },
            {
              file_path        = "/var/log/httpd/error_log"
              log_group_name   = "HttpErrorLog"
              log_stream_name  = "{instance_id}"
              timestamp_format = "%b %d %H:%M:%S"
            }
          ]
        }
      }
    }
  })
}

4. CloudWatch Logs

  • CloudWatch エージェントは、SSM から取得した設定に基づいてログを収集し、アクセスログとエラーログをCloudWatchロググループに送信
  • ASG のインスタンスごとに異なるログストリーム名を使用して、ログを管理
# ./cloudwatch.tf

# CloudWatchエージェントのログ送信先:
## 1.アクセスロググループ
resource "aws_cloudwatch_log_group" "http_access_log" {
  name              = "HttpAccessLog"
  retention_in_days = 7
}

## 2. エラーロググループ
resource "aws_cloudwatch_log_group" "http_error_log" {
  name              = "HttpErrorLog"
  retention_in_days = 7
}

リソース作成後、動作確認にて問題なし

1. Apacheのアクセスログ

tail -f /var/log/httpd/access_log

2. Apacheのエラーログ確認

tail -f /var/log/httpd/error_log

3. Amazon CloudWatchコンソール

  • AWSコンソールにアクセス
  • 「CloudWatch」→「ロググループ」で、var-log-messagesHttpAccessLogHttpErrorLogの3つのロググループがある
  • 3つのグループでそれぞれのログストリームが作成されておりログ表示できた

4. CloudWatchエージェントのステータス

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
  • エージェントが正常に稼働

5. CloudWatchエージェントの設定ファイルの内容

cat /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
  • 設定ファイルが正しく取得されており、インスタンスIDが設定されている

6. CloudWatchエージェントのログ

cat /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log
  • エージェントの起動状況やエラーの詳細が出力

今回はここまでにしたいと思います。

About

terraform-study23

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors