【Tips】ELBのアクセスログを格納するS3バケットのポリシー記述方法

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。先日、ELBがアクセスログを出力できるようになりましたね。そのアクセスログはS3バケット内に配信されることになります。

管理コンソールから作成する場合、上記ブログエントリでもご紹介している通りのバケットポリシーを設定することになります。しかし、CloudFormationでログ用のバケットを作成し、ポリシーを設定し、そのバケットをELBに設定するには、少々コツが必要です。

公式ドキュメントAttach a Policy to Your Amazon S3 Bucketにある通り、アクセスログは「ドキュメントに記述されている特定のAWSアカウントから」PutObjectされるようです。具体的に、東京リージョンであれば582318560864から送られてくるわけですね。

では、そのMappingを作りましょう。

  "Mappings": {
    "ELBLogger": {
      "us-east-1":      { "AccountID": "127311923021" },
      "us-west-2":      { "AccountID": "797873946194" },
      "us-west-1":      { "AccountID": "027434742980" },
      "eu-west-1":      { "AccountID": "156460612806" },
      "ap-southeast-1": { "AccountID": "114774131450" },
      "ap-southeast-2": { "AccountID": "783225319266" },
      "ap-northeast-1": { "AccountID": "582318560864" },
      "sa-east-1":      { "AccountID": "507241528517" },
      "us-gov-west-1":  { "AccountID": "048591011584" }
    }
  },

そして、そのアカウントに対して、arn:aws:s3:::【バケット名】/AWSLogs/【自アカウントID】/*に対するPutObject権限を与えればいいですね。

  "Resources": {
    "LogBucket" : {
      "Type" : "AWS::S3::Bucket",
      "DeletionPolicy" : "Retain"
    },
    "LogBucketPolicy" : {
      "Type" : "AWS::S3::BucketPolicy",
      "Properties" : {
        "Bucket" : { "Ref" : "LogBucket" },
        "PolicyDocument" : {
          "Id" : "LogBucketPolicy",
          "Statement" : [{
            "Sid" : "WriteAccess",
            "Action" : [ "s3:PutObject" ],
            "Effect" : "Allow",
            "Resource" : { "Fn::Join" : [ "", [
              "arn:aws:s3:::", { "Ref" : "LogBucket" } , "/AWSLogs/", { "Ref" : "AWS::AccountId" }, "/*"
            ]]},
            "Principal" : {
              "AWS" : { "Fn::FindInMap" : [ "ELBLogger", { "Ref": "AWS::Region" }, "AccountID" ]}
            }
          }]
        }
      }
    },

あとはこんなかんじでロードバランサを作れば、ELBのログ格納用バケットの定義は完了です。

    "WebLB" : {
      "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties" : {
        "AccessLoggingPolicy": {
          "Enabled" : "true",
          "S3BucketName" : {"Ref":"LogBucket"}
        },
        ...省略...
      }
    }

まとめ

ちょっと工夫するだけで、全リージョン・全アカウント対応型テンプレートが書けます。本エントリの内容は汎用的ですので、コピペでご活用ください。