From 06d30ddf7db5e23e0c8e5e139545d622fb43b0f0 Mon Sep 17 00:00:00 2001 From: Raphael Bottino Date: Fri, 28 Apr 2023 10:43:18 -0500 Subject: [PATCH 1/3] Adding Sentry option. --- .../cloudone.template.yaml | 245 +++++++++++++----- .../main.template.yaml | 33 +++ 2 files changed, 217 insertions(+), 61 deletions(-) diff --git a/Common/Cloud-Account/aws-cfn-cloud-account-connector/cloudone.template.yaml b/Common/Cloud-Account/aws-cfn-cloud-account-connector/cloudone.template.yaml index e8289808..0a82d2be 100644 --- a/Common/Cloud-Account/aws-cfn-cloud-account-connector/cloudone.template.yaml +++ b/Common/Cloud-Account/aws-cfn-cloud-account-connector/cloudone.template.yaml @@ -23,7 +23,17 @@ Parameters: - jp-1 - ca-1 - de-1 - + CloudOneFeatures: + Description: Comma separated list of Cloud One Features to deploy. Defaults to deploy Sentry. + More info at https://cloudone.trendmicro.com/docs/cloud-account-management/api-reference/tag/AWS#operation/describeAWSStackTemplate + Type: String + Default: cloud-sentry + RegionsToDeploy: + Description: Comma separated list of AWS Regions where the Features will be deployed to. If empty, all accessible regions will be used. + More info at https://cloudone.trendmicro.com/docs/cloud-account-management/api-reference/tag/AWS#operation/describeAWSStackTemplate + Type: String + Default: "" + Resources: CloudOneIntegrationStack: @@ -33,7 +43,7 @@ Resources: CloudOneRegion: !Ref CloudOneRegion CloudOneAccountID: !Ref CloudOneAccountID CloudOneOIDCProviderURL: !Sub 'cloudaccounts.${CloudOneRegion}.cloudone.trendmicro.com' - TemplateURL: !Sub 'https://cloud-one-cloud-accounts-${AWS::Region}.s3.${AWS::Region}.amazonaws.com/templates/aws/cloud-account-management-role.template' + TemplateURL: !GetAtt GetCloudOneIntegrationTemplate.templateURL AddAWSAccountToCloudOneFunction: Type: AWS::Lambda::Function @@ -51,63 +61,61 @@ Resources: CloudOneApiKey: !Ref CloudOneApiKey Code: ZipFile: - !Sub - |- - import json - import os - import urllib3 - import boto3 - import cfnresponse - - def lambda_handler(event, context): - status = cfnresponse.SUCCESS - response_data = {} - physicalResourceId = None - try: - - cloudOneRoleArn = os.environ['CloudOneRoleArn'] - cloudOneRegion = os.environ['CloudOneRegion'] - cloudOneApiKey = os.environ['CloudOneApiKey'] - - headers = { - 'api-version': 'v1', - 'Authorization': 'ApiKey '+cloudOneApiKey+'', - 'Content-Type': 'application/json' - } + |- + import json + import os + import urllib3 + import cfnresponse + + def lambda_handler(event, context): + status = cfnresponse.SUCCESS + response_data = {} + physicalResourceId = None + try: + + cloudOneRoleArn = os.environ['CloudOneRoleArn'] + cloudOneRegion = os.environ['CloudOneRegion'] + cloudOneApiKey = os.environ['CloudOneApiKey'] + + headers = { + 'api-version': 'v1', + 'Authorization': 'ApiKey '+cloudOneApiKey+'', + 'Content-Type': 'application/json' + } - http = urllib3.PoolManager() + http = urllib3.PoolManager() + + + if event["RequestType"] == "Create" or event["RequestType"] == "Update": + url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws' + + payload = json.dumps({ + 'roleARN': cloudOneRoleArn + }) + encoded_payload = payload.encode("utf-8") + print(url) + response = http.request("POST", url=url, headers=headers, body=encoded_payload) + print(response) + response_json_data = json.loads(response.data.decode("utf-8")) + print(response_json_data) + physicalResourceId = response_json_data["id"] + response_data = {"ID": response_json_data["id"]} + + else: # if event["RequestType"] == "Delete": + id = event["PhysicalResourceId"] + + url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws/' + id + + print(url) + response = http.request("DELETE", url=url, headers=headers) + print(response) - if event["RequestType"] == "Create" or event["RequestType"] == "Update": - - url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws' - - payload = json.dumps({ - 'roleARN': cloudOneRoleArn - }) - encoded_payload = payload.encode("utf-8") - print(url) - response = http.request("POST", url=url, headers=headers, body=encoded_payload) - print(response) - response_json_data = json.loads(response.data.decode("utf-8")) - print(response_json_data) - physicalResourceId = response_json_data["id"] - response_data = {"ID": response_json_data["id"]} - - else: # if event["RequestType"] == "Delete": - id = event["PhysicalResourceId"] - - url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws/' + id - - print(url) - response = http.request("DELETE", url=url, headers=headers) - print(response) - - except Exception as e: - print(e) - status = cfnresponse.FAILED - - cfnresponse.send(event, context, status, response_data, physicalResourceId) + except Exception as e: + print(e) + status = cfnresponse.FAILED + + cfnresponse.send(event, context, status, response_data, physicalResourceId) AddAWSAccountToCloudOne: Type: AWS::CloudFormation::CustomResource @@ -128,9 +136,124 @@ Resources: - sts:AssumeRole Path: "/" ManagedPolicyArns: - - Fn::Join: - - "" - - - "arn:" - - Ref: AWS::Partition - - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + + GetCloudOneIntegrationTemplateFunction: + Type: AWS::Lambda::Function + Properties: + Runtime: python3.9 + Architectures: + - arm64 + Timeout: 60 + Handler: index.lambda_handler + Role: !GetAtt GetCloudOneIntegrationTemplateFunctionRole.Arn + Environment: + Variables: + CloudOneRegion: !Ref CloudOneRegion + CloudOneApiKey: !Ref CloudOneApiKey + AWSRegion: !Ref AWS::Region + CloudOneFeatures: !Ref CloudOneFeatures + RegionsToDeploy: !Ref RegionsToDeploy + Code: + ZipFile: + |- + import json + import os + import urllib3 + import boto3 + import cfnresponse + + ec2 = boto3.client('ec2') + + def lambda_handler(event, context): + status = cfnresponse.SUCCESS + response_data = {} + physicalResourceId = None + try: + + cloudOneRegion = os.environ['CloudOneRegion'] + cloudOneApiKey = os.environ['CloudOneApiKey'] + aws_region = os.environ['AWSRegion'] or os.environ['AWS_REGION'] + features = os.environ['CloudOneFeatures'] + regions_to_deploy = os.environ['RegionsToDeploy'] + + headers = { + 'api-version': 'v1', + 'Authorization': 'ApiKey '+cloudOneApiKey+'', + 'Content-Type': 'application/json' + } + + http = urllib3.PoolManager() + + if event["RequestType"] == "Create" or event["RequestType"] == "Update": + + if not regions_to_deploy: + response = [region['RegionName'] for region in ec2.describe_regions()['Regions']] + print('Regions:', response) + regions_to_deploy = ",".join(response) + + url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws/templates' + + query_parameters = { + "features": features, + "awsRegion": aws_region, + "featureAWSRegions": regions_to_deploy + } + + print(url) + response = http.request("GET", url=url, headers=headers, fields=query_parameters) + print(response) + response_json_data = json.loads(response.data.decode("utf-8")) + print(response_json_data) + physicalResourceId = response_json_data["templateURL"] + response_data = { + "templateURL": response_json_data["templateURL"], + "parameters": response_json_data["parameters"] + } + + else: # if event["RequestType"] == "Delete": + id = event["PhysicalResourceId"] + + url = 'https://cloudaccounts.'+cloudOneRegion+'.cloudone.trendmicro.com/api/cloudaccounts/aws/' + id + + print(url) + response = http.request("DELETE", url=url, headers=headers) + print(response) + + except Exception as e: + print(e) + status = cfnresponse.FAILED + + cfnresponse.send(event, context, status, response_data, physicalResourceId) + + GetCloudOneIntegrationTemplate: + Type: AWS::CloudFormation::CustomResource + Properties: + ServiceToken: !GetAtt GetCloudOneIntegrationTemplateFunction.Arn + + GetCloudOneIntegrationTemplateFunctionRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: "/" + ManagedPolicyArns: + - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + Policies: + - PolicyName: GetAvailableRegions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - ec2:DescribeRegions + Resource: '*' + diff --git a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml index c9b6442c..84a5717c 100644 --- a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml +++ b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml @@ -29,6 +29,27 @@ Parameters: Description: Cloud One API Key. You can learn more about it at https://cloudone.trendmicro.com/docs/identity-and-account-management/c1-api-key/ Type: String NoEcho: true + # DeployCloudTrailIntegration: + # Description: Decides if the CloudTrail integration should be deployed. Defaults to True. + # Type: String + # AllowedValues: + # - "True" + # - "False" + # Default: "True" + DeployCloudSentry: + Description: Decides if the Cloud Sentry integration should be deployed. Defaults to True. + Type: String + AllowedValues: + - "True" + - "False" + Default: "True" + DeployNetworkSecurityIntegration: + Description: Decides if the Network Security integration should be deployed. Defaults to True. + Type: String + AllowedValues: + - "True" + - "False" + Default: "True" VisionOneServiceToken: Description: Vision One Service Token. See step 1 at https://docs.trendmicro.com/en-us/enterprise/trend-micro-xdr-help/ConfiguringCloudOneWorkloadSecurity/ Type: String @@ -72,6 +93,17 @@ Conditions: HasNoExistingCloudtrailBucketName: !Equals ["True", !Ref CreateNewTrail] + DeployCloudSentry: + !Equals [!Ref DeployCloudSentry, "True"] + + DeployNetworkSecurityIntegration: + !Equals [!Ref DeployNetworkSecurityIntegration, "True"] + + DeployCloudSentryAndNetworkSecurityIntegration: + !And + - !Equals [!Ref DeployCloudSentry, "True"] + - !Equals [!Ref DeployNetworkSecurityIntegration, "True"] + Resources: GetCloudOneRegionAndAccountStack: Type: AWS::CloudFormation::Stack @@ -106,6 +138,7 @@ Resources: CloudOneRegion: !GetAtt GetCloudOneRegionAndAccountStack.Outputs.CloudOneRegion CloudOneAccountID: !GetAtt GetCloudOneRegionAndAccountStack.Outputs.CloudOneAccountId CloudOneApiKey: !Ref CloudOneApiKey + CloudOneFeatures: !If [DeployCloudSentryAndNetworkSecurityIntegration, "cloud-sentry,network-security-deployment", !If [DeployCloudSentry, "cloud-sentry", !If [DeployNetworkSecurityIntegration, "network-security-deployment", ""]]] TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}Common/Cloud-Account/aws-cfn-cloud-account-connector/cloudone.template.yaml' DependsOn: - VisionOneEnrollmentStack From 81181433a5dd0fec6d77aba722bf4f6a9b2eecb6 Mon Sep 17 00:00:00 2001 From: Raphael Bottino Date: Fri, 28 Apr 2023 13:48:02 -0500 Subject: [PATCH 2/3] Dummy. --- .../aws-cfn-cloud-account-connector/main.template.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml index 84a5717c..c248cef6 100644 --- a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml +++ b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml @@ -23,7 +23,6 @@ Metadata: VisionOneServiceToken: default: VisionOneServiceToken - Parameters: CloudOneApiKey: Description: Cloud One API Key. You can learn more about it at https://cloudone.trendmicro.com/docs/identity-and-account-management/c1-api-key/ From 5618674c2c4870298fb2815f4031d96c635dbcac Mon Sep 17 00:00:00 2001 From: Raphael Bottino Date: Mon, 1 May 2023 09:51:33 -0500 Subject: [PATCH 3/3] Updating README.md. Adding new parameters to ParameterGroup. --- .../Cloud-Account/aws-cfn-cloud-account-connector/README.md | 6 +++++- .../aws-cfn-cloud-account-connector/main.template.yaml | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Common/Cloud-Account/aws-cfn-cloud-account-connector/README.md b/Common/Cloud-Account/aws-cfn-cloud-account-connector/README.md index b2a538bd..a569e742 100644 --- a/Common/Cloud-Account/aws-cfn-cloud-account-connector/README.md +++ b/Common/Cloud-Account/aws-cfn-cloud-account-connector/README.md @@ -1,6 +1,6 @@ # Add AWS Account to Cloud One -To fully integrate an AWS account in Cloud One, you must deploy resources in your AWS account and do manual steps in Trend Cloud One dashboard. This CloudFormation template automates all these steps on your behalf, including integrating it to Vision One. +To fully integrate an AWS account in Cloud One, you must deploy resources in your AWS account and do manual steps in Trend Cloud One dashboard. This CloudFormation template automates all these steps on your behalf, including integrating it to Vision One. You can also optionally also deploy Sentry and Network Security with hosted infrastructure to these AWS accounts via this automation. ## What does it actually do? @@ -47,6 +47,10 @@ To fully integrate an AWS account in Cloud One, you must deploy resources in you - Description: Decides if a new Trail should be created. Defaults to False, so you must enter a S3 Bucket name in the ExistingCloudtrailBucketName parameter. In case you pick True, a new trail and bucket will be created for you. Setting this to True will incur in extra costs. - ExistingCloudtrailBucketName: - Description: Specify the name of an existing bucket that you want to use for forwarding to Trend Micro Cloud One. Only used if CreateNewTrail is set to False. +- DeployCloudSentry: + - Description: Decides if the Cloud Sentry integration should be deployed. Defaults to True. +- DeployNetworkSecurityIntegration: + - Description: Decides if the Network Security integration should be deployed. Defaults to True. ### Shouldn't be Changed from Default diff --git a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml index c248cef6..656d1b77 100644 --- a/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml +++ b/Common/Cloud-Account/aws-cfn-cloud-account-connector/main.template.yaml @@ -11,6 +11,8 @@ Metadata: - VisionOneServiceToken - CreateNewTrail - ExistingCloudtrailBucketName + - DeployCloudSentry + - DeployNetworkSecurityIntegration - Label: default: 'Warning: Do not modify the fields below unless you know what you are doing. Modifications may cause your deployment to fail.'