【CloudFormation】VPC Flow Logsをデプロイしてみる(CloudWatch Logs,S3)
1. はじめに
こんにちわ、Mitsuoです。
色んな方の技術ブログを見ていたのですが、端的に書いているのが一番分かりやすいなと思いました。
シンプルに書いていけるように頑張っていきます。
2. 今回のお題
今回はCloudFormationを用いてVPC Flow Logsをデプロイしてみました。
VPCフローログの仕様に関する解説は無いので、公式ドキュメントや他の技術ブログを参照ください。
Logging IP traffic using VPC Flow Logs
3. 作成したリソース
テンプレートで作成するリソースは以下の通りです。
-
ログ保管先がCloudWatch Logs
- IAMロール
- ロググループ
- フローログ
-
ログ保管先がS3バケット
- S3バケット
- フローログ
ログの保管先がCloudWatch Logs、S3かによって、作成するリソースを分ける様にしています。
このテンプレートを利用する前に、フローログを作成するVPCを準備してください。
Parameterセクションで選択したVPC IDに対して設定します。
テンプレートにはEC2は含まれていないです。
ログを出力する検証のために後から手動で作成しています。
4 テンプレート情報
作成したテンプレートになります。
AWSTemplateFormatVersion: "2010-09-09"
Description: Create VPC Flow Logs and related resources.
# ------------------------------------------------------------#
# Caution:
# This template is for deploying the Flow logs in existing VPC. In addition to Flow logs, it deploys related resources such as bucket.
# log group and IAM Role depending on LogType.
# For more information, see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html
#
# ------------------------------------------------------------#
# Metadata:
# This can privide details about the template.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html.
# As Metadata Keys, AWS::CloudFormation::Interface can Defines the grouping and ordering of input parameters
# when they are displayed in the AWS CloudFormation console.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-interface.html.
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
-
Parameters:
- SystemName
- EnvType
- Tagprefix
- Owner
- VPCID
- FilterType
- LogType
- RetentionDays
ParameterLabels:
SystemName:
default: "Type the Systemname"
EnvType:
default: "Select the environment in which you deploy resources"
Tagprefix:
default: "Type the Tagprefix which is logical unit name about this stack(e.g. Webserver,Monitoring,Logging)"
Owner:
default: "Type who owns these resources (e.g. project name or worker, whether this purpose is just verification or not)"
VPCID:
default: "Select the VPC ID"
FilterType:
default: "Select the type of traffic to capture (Accept, Reject, or All traffic)"
LogType:
default: "Select the type of Log sent to(CloudWatch Logs or S3 Bucket)"
RetentionDays:
default: "Select the duration of retention for CloudWatch Logs"
# ------------------------------------------------------------#
# Parameters
# This Can enable templates to input custom values each time you create or update a stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html.
# ------------------------------------------------------------#
Parameters:
SystemName:
Type: String
EnvType:
Type: String
Default: "dev"
AllowedValues:
- dev
- stg
- prod
Tagprefix:
Type: String
Owner:
Type: String
VPCID:
Type: AWS::EC2::VPC::Id
ConstraintDescription: "Select the VPC ID"
FilterType:
Type: String
Default: ALL
AllowedValues: [ ALL, ACCEPT, REJECT ]
LogType:
Type: String
Default: cloud-watch-logs
AllowedValues: [ cloud-watch-logs, s3 ]
RetentionDays:
Type: Number
Default: 30
AllowedValues: [ 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 2192, 2557, 2922, 3288, 3653 ]
Conditions:
EqualtoLogs: !Equals [!Ref LogType, cloud-watch-logs]
Equaltos3: !Equals [!Ref LogType, s3]
# ------------------------------------------------------------#
# Resources
# This can declare the AWS resources that you want to include in the stack.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
# Create Logs(CloudWatch) and VPC Flow Logs.
# In case of destination for logging is cloud-watch-logs, you can create these resources below.
# ------------------------------------------------------------#
IAMRoleforFlowlogs:
Type: "AWS::IAM::Role"
Condition: "EqualtoLogs"
Properties:
RoleName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-flowlogs-iamrole
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "vpc-flow-logs.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
- PolicyName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-flowlogs-iampolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "logs:DescribeLogGroups"
- "logs:DescribeLogStreams"
Resource: "*"
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-flowlogs-iamrole
- Key: Owner
Value: !Sub ${Owner}
LogsforFlowlogs:
Type: "AWS::Logs::LogGroup"
Condition: "EqualtoLogs"
Properties:
LogGroupName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-logging
RetentionInDays: !Ref RetentionDays
Tags:
- Key: Name
Value: !Sub!Sub ${SystemName}-${EnvType}-${Tagprefix}-logging
- Key: Owner
Value: !Sub ${Owner}
VPCFlowLogs1:
Type: AWS::EC2::FlowLog
Condition: "EqualtoLogs"
Properties:
DeliverLogsPermissionArn: !GetAtt IAMRoleforFlowlogs.Arn
LogDestinationType: !Ref LogType
LogGroupName: !Ref LogsforFlowlogs
MaxAggregationInterval: 600
ResourceId: !Ref VPCID
ResourceType: VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-flowlogs
- Key: Owner
Value: !Sub ${Owner}
TrafficType: !Ref FilterType
DependsOn: [ IAMRoleforFlowlogs, LogsforFlowlogs ]
# ------------------------------------------------------------#
# Create S3 Bucket and VPC Flow Logs.
# In case of destination for logging is s3, you can create these resources below.
# ------------------------------------------------------------#
S3BucketforFlowlogs:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Retain
Condition: "Equaltos3"
Properties:
BucketName: !Sub ${SystemName}-${EnvType}-${Tagprefix}-s3bucket-logging-${AWS::AccountId}
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Suspended
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- Id: !Sub ${SystemName}-${EnvType}-${Tagprefix}-lifecycle-s3bucket-logging
Status: Enabled
ExpirationInDays: 30
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerEnforced
NotificationConfiguration:
EventBridgeConfiguration:
EventBridgeEnabled: true
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-s3bucket-logging-${AWS::AccountId}
- Key: Owner
Value: !Sub ${Owner}
VPCFlowLogs2:
Type: AWS::EC2::FlowLog
Condition: "Equaltos3"
Properties:
DestinationOptions:
FileFormat: plain-text
HiveCompatiblePartitions: false
PerHourPartition: false
LogDestination: !Sub "arn:aws:s3:::${S3BucketforFlowlogs}"
LogDestinationType: !Ref LogType
MaxAggregationInterval: 600
ResourceId: !Ref VPCID
ResourceType: VPC
Tags:
- Key: Name
Value: !Sub ${SystemName}-${EnvType}-${Tagprefix}-flowlogs
- Key: Owner
Value: !Sub ${Owner}
TrafficType: !Ref FilterType
DependsOn: S3BucketforFlowlogs
# ------------------------------------------------------------#
# Outputs
# This can output each value specified as output section.
# For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html.
# ------------------------------------------------------------#
Outputs:
# ------------------------------------------------------------#
# For CloudWatch logs
# ------------------------------------------------------------#
IAMRoleforFlowlogs:
Description: IAMRoleforFlowlogs
Value: !Ref IAMRoleforFlowlogs
Condition: "EqualtoLogs"
LogsforFlowlogs:
Description: LogsforFlowlogs
Value: !Ref LogsforFlowlogs
Condition: "EqualtoLogs"
VPCFlowLogs1:
Description: VPCFlowLogs1
Value: !Ref VPCFlowLogs1
Condition: "EqualtoLogs"
# ------------------------------------------------------------#
# For S3 Bucket
# ------------------------------------------------------------#
VPCFlowLogsS3Bucket:
Description: S3BucketforFlowlogs
Value: !Ref S3BucketforFlowlogs
Condition: "Equaltos3"
VPCFlowLogs2:
Description: VPCFlowLogs2
Value: !Ref VPCFlowLogs2
Condition: "Equaltos3"
5. テンプレートの補足
テンプレートに関して、以下の通り補足します。
5.1 Metadata/Parameters
メタデータおよびパラメターセクションで、以下の値を定義します。
項目 | 備考 |
---|---|
SystemName |
プロジェクト名や利用目的等を入力する |
EnvType |
デプロイする環境を選択する 検証、ステージング、本番の3点 |
Tagprefix |
任意で入力するPrefix値 |
Owner |
作業者、所有者、コスト管理用に入力する |
VPCID |
フローログを作成するVPC情報を入力する |
FilterType |
取得するトラフィックの種類を選択する ACCEPT 許可されたトラフィックのみ REJECT 拒否されたトラフィックのみ ALL 全てのトラフィック |
LogType |
フローログの格納先を選択する cloud-watch-logs CloudWatch Logs s3 S3バケット |
RetentionDays |
フローログを格納先をCloudWatch Logsにした場合、保管する期間を指定する |
-
テンプレートで生成する各リソース名とNameタグの値に、
SystemName
、EnvType
、Tagprefix
の3点を含みます。-
Owner
はOwnerタグの値に利用します。
-
-
Parameterに入力する関係で
RetentionDays
は格納先がS3の場合でも入力する必要があります。- S3の場合はライフサイクル設定で30日固定にしています。変更されたい場合はプロパティ側の値を直接変更するか、Parameterに追加する等の工夫が必要です。
5.2 想定ユースケース
今回のテンプレートは、次の様なユースケースを想定して作成しました。
- フローログは顧客の要望に応じて、CloudWatch Logs、S3の好きな方に格納する
- Conditionsセクションで
LogType
に応じて作成するリソースを分けている
- Conditionsセクションで
- デフォルトフォーマットで使用する
- カスタムフォーマットに変更したい場合は、プロパティで
LogFormat
を用いる必要がある
- カスタムフォーマットに変更したい場合は、プロパティで
- フローログを作成するリソースは「VPC」
- VPC、サブネット、ネットワークインタフェースのいずれかから選択できるが、このテンプレートでは「VPC」固定にしている
- フローログの集約期間は10分
- ファイルフォーマットはデフォルト
- parquetを利用したい場合は
DestinationOptions
のFileFormat
をplain-text
から変更する -
HiveCompatiblePartitions
はfalse
-
PerHourPartition
はfalse
のログのパーティーションを変更したい場合はTrue
に変更する
- parquetを利用したい場合は
5.3 動作確認
実際に動作を確認してみます。
上記のテンプレートを用いてLogs用とS3用のフローログを作成します。
スタック名:FlowLogs-ClouWatchLogs
格納先がCloudWatch Logs
項目 | 備考 |
---|---|
SystemName |
mitsuo1 |
EnvType |
dev |
Tagprefix |
logging |
Owner |
mitsuo |
VPCID |
別途作成済みのVPCID |
FilterType |
ALL |
LogType |
cloud-watch-logs |
RetentionDays |
30 |
スタック名:FlowLogs-S3
格納先がS3バケット
項目 | 備考 |
---|---|
SystemName |
mitsuo2 |
EnvType |
dev |
Tagprefix |
logging |
Owner |
mitsuo |
VPCID |
別途作成済みのVPCID |
FilterType |
ALL |
LogType |
s3 |
RetentionDays |
30 |
ではスタックを作成します。
VPCにフローログが作成されたことを確認します。
VPC内にEC2を2台作成し、一方のインスタンスからもう一方のインスタンスに対してpingコマンドを実行します。
続いてフローログが出力されている事を確認します。
CloudWatch Logs
S3バケット
また、S3バケットの場合は、バケットポリシーが自動的に追加された事が確認できています。
XXXXXXXXXXXXにはアカウントIDが入ります。
{
"Version": "2012-10-17",
"Id": "AWSLogDeliveryWrite20150319",
"Statement": [
{
"Sid": "AWSLogDeliveryWrite",
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::mitsuo2-dev-logging-s3bucket-logging-XXXXXXXXXXXX/AWSLogs/XXXXXXXXXXXX/*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "XXXXXXXXXXXX",
"s3:x-amz-acl": "bucket-owner-full-control"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:logs:ap-northeast-1:XXXXXXXXXXXX:*"
}
}
},
{
"Sid": "AWSLogDeliveryAclCheck",
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::mitsuo2-dev-logging-s3bucket-logging-XXXXXXXXXXXX",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "XXXXXXXXXXXX"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:logs:ap-northeast-1:XXXXXXXXXXXX:*"
}
}
}
]
}
5.4 まとめ
顧客の要望によって可変になる部分はどうしてもありますが、なるべく標準化をする事が出来たのではないでしょうか。
S3ログへ直接格納できる機能は後からリリースされたので、テンプレートが分かれて紹介されるケースはよくありますが、まとめた物があまりなかったので作ってみました。
設定する単位がVPC、サブネットなどのリソース毎になるので、別にテンプレートが分かれてても良いのでは?と思った事は秘密です
このブログが誰かの役に立てばと思います。Mituoでした!!
Discussion