MackerelのAWSインテグレーションで必要なRoleをCloudFormation一撃で作ってみる(外部ID, SES, StepFunctions対応)
AWS事業本部 梶原@福岡オフィスです。以前
https://dev.classmethod.jp/cloud/mackerel-aws-role-cloudformation/
Mackerelで自分が監視したいサービスのReadOnly権限を選んで作成できるCloudFormationテンプレートを作りました!!! そう、後から別のサービスの監視追加をしたい時は、テンプレートの更新をしてパラメータを変更すればいいだけです。(すばら
と言ってたら、
「外部IDの更新ができないよ。」
という声をきいて、更新しようと調べていたら、いつの間にか、SESとStepFunctionsがAWS Integrationに追加されていたので勢いあまって追加更新しました。
https://mackerel.io/ja/blog/archive/2019/05/29
割り当てるロールの権限などはMackerelの公式ドキュメントに沿っています。 https://mackerel.io/ja/docs/entry/integrations/aws
ということで、さくさく行きます。
※API Gatewayのリソースは東京リージョン(ap-northeast-1::/*)としてますので、他のリージョンの場合は適時変更ください
MackerelのAWSインテグレーションの作成
1. AWSコンソールにログイン
https://ap-northeast-1.console.aws.amazon.com/console/home?region=ap-northeast-1#
2. このボタンをポチっとする。
3. Mackerel のAWS Integrationの作成のページから外部IDを取得して設定する(New!)
https://mackerel.io/my?tab=awsIntegration
CloudFormationのパラメータのExternalIdに入力する
4. CloudFormationのパラメータで監視が必要なサービスを選択(true)にする。
パラメータのデフォルト設定ではEC2, RDS, Redshift, CloudFront, Lambdaを有効にしています
ので、監視したいサービスをtrue
または、監視しない(権限を渡したくない)場合はfalse
に変更してください
※全部選んで(10くらい)、エラーが発生した場合は、ポリシーの上限緩和を実施しているかご確認ください。また、必要に応じて上限緩和をおこなってください。
5. CloudFormationの実行をします。
□AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。 のチェックをいれてください
6. OutputにMackerel用のRoleのArnがでてくる
メモります。
7. MackerelのAWSインテグレーションの作成画面にもどってOutputのRoleのArnを設定します。
ここで作成 -> https://mackerel.io/my?tab=awsIntegration
上でコピーしたARNを入れます。
リージョンを選択します。有効な場合はロールArnの横に☑がつくので確認してください。
8. 監視する
で、後は、Mackerelで、いい感じに監視しちゃってください!(今年2度目)
監視方法はdevelopre.IOのMackerel特集などをご参考に https://dev.classmethod.jp/?s=mackerel
まとめ
割り当てるロールの権限などはMackerelの公式ドキュメントに沿っています。 https://mackerel.io/ja/docs/entry/integrations/aws
Mackerelは更新が速いので、ほんとこれ・・・ CloudFormationのスタックのアップデートでできるようにしといてよかった。 外部IDの更新により、セキュリティは向上していますので、これからも積極的に対応していきたいです。
自分でRoleつくるって、ちょっとハードル高いと思ってるので、少し低くできたらなら幸いです。 Cloudfromtaionのパラメータでの条件設定、Role作成の分岐などもご参考になれば。
テンプレートはこちら
AWSTemplateFormatVersion: "2010-09-09" Description: "IAM Assume Role for Mackerel" Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "External ID" Parameters: - ExternalId - Label: default: "Compute" Parameters: - AmazonEC2ReadOnlyAccess - ECSReadOnlyAccess - AWSLambdaReadOnlyAccess - Label: default: "Storage" Parameters: - AmazonS3ReadOnlyAccess - Label: default: "Database" Parameters: - AmazonRDSReadOnlyAccess - AmazonDynamoDBReadOnlyAccess - AmazonElastiCacheReadOnlyAccess - AmazonRedshiftReadOnlyAccess - Label: default: "Networking & Content Delivery" Parameters: - CloudFrontReadOnlyAccess - APIGatewayReadOnlyAccess - Label: default: "Analytics" Parameters: - AmazonKinesisReadOnlyAccess - AmazonESReadOnlyAccess - Label: default: "Application Integration" Parameters: - AWSStepFunctionsReadOnlyAccess - AmazonSQSReadOnlyAccess - Label: default: "Customer Engagement" Parameters: - AmazonSESReadOnlyAccess - Label: default: "Management & Governance" Parameters: - CloudWatchReadOnlyAccess ParameterLabels: ExternalId: default: "Mackerel AWS Integration External Id" AmazonEC2ReadOnlyAccess: default: "EC2, ELB (CLB), ALB, NLB" ECSReadOnlyAccess: default: "ECS" AWSLambdaReadOnlyAccess: default: "Lambda" AmazonS3ReadOnlyAccess: default: "S3" AmazonRDSReadOnlyAccess: default: "RDS" AmazonDynamoDBReadOnlyAccess: default: "DynamoDB" AmazonElastiCacheReadOnlyAccess: default: "ElastiCache" AmazonRedshiftReadOnlyAccess: default: "Redshift" CloudFrontReadOnlyAccess: default: "CloudFront" APIGatewayReadOnlyAccess: default: "API Gateway" AmazonKinesisReadOnlyAccess: default: "Kinesis" AmazonESReadOnlyAccess: default: "ES" AmazonSQSReadOnlyAccess: default: "SQS" AmazonSESReadOnlyAccess: default: "SES" AWSStepFunctionsReadOnlyAccess: default: "Step Functions" CloudWatchReadOnlyAccess: default: "CloudWatch" Parameters: ExternalId: Description: Please update External ID (https://mackerel.io/my?tab=awsIntegration) Default: Mackerel-AWS-Integration Type: String AmazonEC2ReadOnlyAccess: Description: Monitoring EC2 Type: String Default: yes AllowedValues: [yes, no] AmazonRDSReadOnlyAccess: Description: Monitoring RDS Type: String Default: yes AllowedValues: [yes, no] AmazonElastiCacheReadOnlyAccess: Description: Monitoring ElastiCache Type: String Default: yes AllowedValues: [yes, no] AmazonRedshiftReadOnlyAccess: Description: Monitoring Redshift Type: String Default: no AllowedValues: [yes, no] AWSLambdaReadOnlyAccess: Description: Monitoring AWS Lambda Type: String Default: no AllowedValues: [yes, no] AmazonSQSReadOnlyAccess: Description: Monitoring SQS Type: String Default: no AllowedValues: [yes, no] AmazonDynamoDBReadOnlyAccess: Description: Monitoring DynamoDB Type: String Default: no AllowedValues: [yes, no] CloudFrontReadOnlyAccess: Description: Monitoring CloudFront Type: String Default: no AllowedValues: [yes, no] APIGatewayReadOnlyAccess: Description: Monitoring API Gateway (apigateway:GET, apigateway:OPTIONS) Type: String Default: no AllowedValues: [yes, no] AmazonKinesisReadOnlyAccess: Description: Monitoring Kinesis Type: String Default: no AllowedValues: [yes, no] AmazonS3ReadOnlyAccess: Description: Monitoring S3 Type: String Default: no AllowedValues: [yes, no] AmazonESReadOnlyAccess: Description: Monitoring ES Type: String Default: no AllowedValues: [yes, no] ECSReadOnlyAccess: Description: Monitoring ECS (ecs:Describe*, ecs:List*) Type: String Default: no AllowedValues: [yes, no] AmazonSESReadOnlyAccess: Description: Monitoring SES (ses:Describe*) Type: String Default: no AllowedValues: [yes, no] AWSStepFunctionsReadOnlyAccess: Description: Monitoring Step Functions Type: String Default: no AllowedValues: [yes, no] CloudWatchReadOnlyAccess: Description: Monitoring CloudWatch (if CloudFront only, API Gateway only, Kinesis only, S3 only, ES only, ECS only, SES only, Step Functions only) Type: String Default: no AllowedValues: [yes, no] Conditions: AmazonEC2ReadOnlyAccess: !Equals [ !Ref AmazonEC2ReadOnlyAccess, yes ] AmazonRDSReadOnlyAccess: !Equals [ !Ref AmazonRDSReadOnlyAccess, yes ] AmazonElastiCacheReadOnlyAccess: !Equals [ !Ref AmazonElastiCacheReadOnlyAccess, yes ] AmazonRedshiftReadOnlyAccess: !Equals [ !Ref AmazonRedshiftReadOnlyAccess, yes ] AWSLambdaReadOnlyAccess: !Equals [ !Ref AWSLambdaReadOnlyAccess, yes ] AmazonSQSReadOnlyAccess: !Equals [ !Ref AmazonSQSReadOnlyAccess, yes ] AmazonDynamoDBReadOnlyAccess: !Equals [ !Ref AmazonDynamoDBReadOnlyAccess, yes ] CloudFrontReadOnlyAccess: !Equals [ !Ref CloudFrontReadOnlyAccess, yes ] APIGatewayReadOnlyAccess: !Equals [ !Ref APIGatewayReadOnlyAccess, yes ] AmazonKinesisReadOnlyAccess: !Equals [ !Ref AmazonKinesisReadOnlyAccess, yes ] AmazonS3ReadOnlyAccess: !Equals [ !Ref AmazonS3ReadOnlyAccess, yes ] AmazonESReadOnlyAccess: !Equals [ !Ref AmazonESReadOnlyAccess, yes ] ECSReadOnlyAccess: !Equals [ !Ref ECSReadOnlyAccess, yes ] AmazonSESReadOnlyAccess: !Equals [ !Ref AmazonSESReadOnlyAccess, yes ] AWSStepFunctionsReadOnlyAccess: !Equals [ !Ref AWSStepFunctionsReadOnlyAccess, yes ] CloudWatchReadOnlyAccess: !Equals [ !Ref CloudWatchReadOnlyAccess, yes ] Resources: MackerelAWSIntegrationRole: Type: AWS::IAM::Role Properties: RoleName: "MackerelAWSIntegrationRole" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Action: "sts:AssumeRole" Effect: "Allow" Principal: AWS: "arn:aws:iam::217452466226:root" Condition: StringEquals: sts:ExternalId: !Ref ExternalId ManagedPolicyArns: - !If [AmazonEC2ReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonRDSReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonElastiCacheReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonElastiCacheReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonRedshiftReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonRedshiftReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AWSLambdaReadOnlyAccess, "arn:aws:iam::aws:policy/AWSLambda_ReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonSQSReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonSQSReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonDynamoDBReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess", !Ref "AWS::NoValue"] - !If [CloudFrontReadOnlyAccess, "arn:aws:iam::aws:policy/CloudFrontReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonKinesisReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonKinesisReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonS3ReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AmazonESReadOnlyAccess, "arn:aws:iam::aws:policy/AmazonESReadOnlyAccess", !Ref "AWS::NoValue"] - !If [AWSStepFunctionsReadOnlyAccess, "arn:aws:iam::aws:policy/AWSStepFunctionsReadOnlyAccess", !Ref "AWS::NoValue"] - !If [CloudWatchReadOnlyAccess, "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess", !Ref "AWS::NoValue"] APIGatewayGetPolicy: Condition: APIGatewayReadOnlyAccess Type: AWS::IAM::Policy Properties: PolicyName: "APIGatewayGetPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - apigateway:GET - apigateway:OPTIONS Resource: arn:aws:apigateway:ap-northeast-1::/* Roles: - !Ref MackerelAWSIntegrationRole ECSDescribePolicy: Condition: ECSReadOnlyAccess Type: AWS::IAM::Policy Properties: PolicyName: "ECSDescribePolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - ecs:Describe* - ecs:List* Resource: "*" Roles: - !Ref MackerelAWSIntegrationRole SESDescribePolicy: Condition: AmazonSESReadOnlyAccess Type: AWS::IAM::Policy Properties: PolicyName: "SESDescribePolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - ses:Describe* Resource: "*" Roles: - !Ref MackerelAWSIntegrationRole Outputs: MackerelAWSIntegrationRoleArn: Value: !GetAtt MackerelAWSIntegrationRole.Arn