CloudFormationでCloudWatch Logsの保存期間をAWS Configでチェックして自動設定する
前回の記事で、CloudWatch Logsの保持期間をAWS Configでチェックして指定期間に修正するという内容をご紹介しました。
前回はコンソールで作業していましたが、それも面倒なのでCloudFormationで設定できるようにしてみました。
CloudFormationテンプレート
早速ですが、テンプレートは以下のとおりです。
--- AWSTemplateFormatVersion: '2010-09-09' Description: check and set retention days of the CloudWatch Logs log group by AWS Config ############################################################### # Metadata ############################################################### Metadata: AWS::CloudFormation::Interface: ParameterGroups: # ------------------------------------------------------------# # Requeired Parameters # ------------------------------------------------------------# - Label: default: Required Parameters Parameters: - ExecutionFrequency - NotificationEmailAddress # ------------------------------------------------------------# # Option Parameters # ------------------------------------------------------------# - Label: default: Option Parameters Parameters: - RetentionInDays - BaseMessage - BaseNotificationSubject ############################################################### # Parameters ############################################################### Parameters: # EB application & Environment RetentionInDays: Description: "(Option) select cloudwatch logs retention days" Default: "Default" Type: String AllowedValues: - Default - 1 - 3 - 5 - 7 - 14 - 30 - 60 - 90 - 120 - 150 - 180 - 365 - 400 - 545 - 731 - 1827 - 3653 BaseMessage: Description: "(Option) enter messages for notification" Default: "Default" Type: String BaseNotificationSubject: Description: "(Option) enter notification subject" Default: "Default" Type: String ExecutionFrequency: Description: "(Required) select execution frequency which AWS Config runs evaluations" Default: TwentyFour_Hours Type: String AllowedValues: - One_Hour - Six_Hour - Three_Hour - Twelve_Hours - TwentyFour_Hours NotificationEmailAddress: Description: "(Required) Enter e-mail address for notification" Type: String ############################################################### # Conditions ############################################################### Conditions: SetRetentionInDays: !Not [ !Equals [ !Ref RetentionInDays, "Default" ] ] SetBaseMessage: !Not [ !Equals [ !Ref BaseMessage, "Default" ] ] SetBaseNotificationSubject: !Not [ !Equals [ !Ref BaseNotificationSubject, "Default" ] ] ############################################################### # Resources ############################################################### Resources: # ------------------------------------------------------------# # IAM Role # ------------------------------------------------------------# IamRole: Type: AWS::IAM::Role Properties: RoleName: ssm-automation-role-for-put-cloudwatch-logs-retention-policy Description: "role for ssm automation" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: "ssm.amazonaws.com" Action: "sts:AssumeRole" Policies: - PolicyName: sns-publish PolicyDocument: Version: "2012-10-17" Statement: Effect: "Allow" Action: "sns:Publish" Resource: "*" - PolicyName: ssm-automation-put-cloudwatch-logs-retention-days PolicyDocument: Version: "2012-10-17" Statement: Effect: "Allow" Action: "logs:PutRetentionPolicy" Resource: "*" # ------------------------------------------------------------# # SSM Automation Document # ------------------------------------------------------------# SetCloudWatchLoggroupRetentionDaysDocument: Type: AWS::SSM::Document Properties: Content: description: Set CloudWatch Log Group Retention period schemaVersion: '0.3' assumeRole: '{{ AutomationAssumeRole }}' parameters: AutomationAssumeRole: type: String description: (Required) The ARN of the role that allows Automation to perform the actions on your behalf. logGroupName: type: String description: (Required) The name of CloudWatch Loggroup. retentionInDays: type: Integer description: (Optional) Retention Days of cloudwatch loggroup. default 365 days. default: 365 BasePublishMessage: type: String description: (Optional) The message to include in the SNS notification. default: There is no retentionInDays set for the cloudwatch logs. And set RetentionInDays the logs. SnsTopicARN: type: String description: (Required) The ARN of the SNS topic to publish the notification to. BaseNotificationSubject: type: String description: (Optional) Subject of the notification. default: CloudWatch Logs Retention Check mainSteps: - name: PutRetentionPolicy action: 'aws:executeAwsApi' inputs: Service: logs Api: PutRetentionPolicy logGroupName: '{{logGroupName}}' retentionInDays: '{{retentionInDays}}' - name: PublishMessage action: 'aws:executeAwsApi' inputs: Service: sns Api: Publish Message: '{{logGroupName}} : {{ BasePublishMessage }}' TopicArn: '{{ SnsTopicARN }}' Subject: '{{ BaseNotificationSubject }} - {{logGroupName}}' isEnd: true DocumentType: Automation Name: SetCloudWatchLoggroupRetentionDays # ------------------------------------------------------------# # AWS Config Rule # ------------------------------------------------------------# ConfigRule: Type: AWS::Config::ConfigRule Properties: ConfigRuleName: cw-loggroup-retention-period-check Description: "Checks whether Amazon CloudWatch LogGroup retention period is set to specific number of days. The rule is NON_COMPLIANT if the retention period is not set or is less than the configured retention period." MaximumExecutionFrequency: !Ref ExecutionFrequency Source: Owner: AWS SourceIdentifier: CW_LOGGROUP_RETENTION_PERIOD_CHECK Scope: ComplianceResourceTypes: - "AWS::Logs::LogGroup" # ------------------------------------------------------------# # AWS Config Remediation Action Configuration # ------------------------------------------------------------# RemediationConfiguration: Type: AWS::Config::RemediationConfiguration Properties: Automatic: true ConfigRuleName: !Ref ConfigRule MaximumAutomaticAttempts: 5 RetryAttemptSeconds: 60 TargetId: !Ref SetCloudWatchLoggroupRetentionDaysDocument TargetType: "SSM_DOCUMENT" TargetVersion: "1" Parameters: AutomationAssumeRole: StaticValue: Values: - !GetAtt [IamRole, "Arn"] logGroupName: ResourceValue: Value: RESOURCE_ID retentionInDays: StaticValue: Values: - !If [ SetRetentionInDays, !Ref RetentionInDays, !Ref AWS::NoValue ] BasePublishMessage: StaticValue: Values: - !If [ SetBaseMessage, !Ref BaseMessage, !Ref AWS::NoValue ] SnsTopicARN: StaticValue: Values: - !Ref NotificationSnsTopic BaseNotificationSubject: StaticValue: Values: - !If [ SetBaseNotificationSubject, !Ref BaseNotificationSubject, !Ref AWS::NoValue ] # ------------------------------------------------------------# # Amazon SNS # ------------------------------------------------------------# NotificationSnsTopic: Type: AWS::SNS::Topic Properties: #DisplayName: String #KmsMasterKeyId: String Subscription: - Endpoint: !Ref NotificationEmailAddress Protocol: "email" TopicName: cloudwatch-logs-retention-day-check
Conditionsの利用
このテンプレートのポイントはConditions
の利用です。
Systems ManagerのAutomationドキュメントでは、パラメータとして必須のものとオプションのもので2種類があります。オプションのパラメータは、AWS Configの修復アクションでは必須ではありません。
必須ではないので、「何も指定しなければAutomationドキュメントのデフォルトが利用」されます。
これをCloudFormationでも実現したかったので、Conditions
を利用してスタック作成時にオプションのパラメータの内容を変更していない場合は、Automationドキュメントのデフォルトを利用するようにしています。
使い方
CloudFormationのコンソールから上記テンプレートファイルをアップロードします。
パラメータの指定は下記図のようにRequired
と記載している項目のみでOKです。
各パラメーターの意味は下記の通りです。
パラメータ | 内容 | 備考 |
---|---|---|
ExecutionFrequency | Twelve_Hours | AWS Configのチェック間隔の指定 |
NotificationEmailAddress | 非準拠リソース検知時の通知先のメールアドレス | |
RetentionInDays | (オプション)ロググループの保持期間(日)の指定 | デフォルトで365日 |
BaseMessage | (オプション)メール通知するメッセージ内容 | |
BaseNotificationSubject | (オプション)通知メールの件名 |
オプションとしている項目(上記画像でDefaultと表示されている項目)は、カスタマイズしたい場合に、その内容を記載してください。デフォルトのままの場合は、Automationドキュメントで指定されているデフォルト値が設定されます。
今回はログの保持期間 (RetentionInDays) をデフォルトの 365 から 400 に変更してみました。
スタックを作成するとAmazon SNSも作成されるので、SNSのサブスクライブ確認のメールが届きます。そのまま「Confirm subsctiption」をクリックして通知が届くようにしておきましょう。
確認
スタックの作成が完了したら AWS Configの画面から確認してみます。デフォルトから変更した保持期間がちゃんと「400日」になっていますね。また、デフォルトから変更していない項目は、修復アクションのパラメータには何も設定されていないことが確認できました。
2つのロググループに保持期間が設定されていないことも検知しています。
再評価してみます。
正常に修復アクションが実行されました。
修復アクションにより ロググループの保持期間が400日(13ヶ月)に変更されました!
最後に
これで簡単にログの保持期間のチェックが設定できるようになりました。もしよろしければご活用ください。
以上です。