diff --git a/.github/workflows/ci-pull-request-modules-foundational.yaml b/.github/workflows/ci-pull-request-modules-foundational.yaml index 4f56963..ffe7054 100644 --- a/.github/workflows/ci-pull-request-modules-foundational.yaml +++ b/.github/workflows/ci-pull-request-modules-foundational.yaml @@ -40,16 +40,9 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: eu-west-1 - - name: Build and Upload CSPM Templates - run: make ci + - name: Publish Templates + run: make publish working-directory: modules/foundational env: S3_BUCKET: cf-templates-cloudvision-ci - S3_PREFIX: pr/${{ github.event.pull_request.number }} - - - name: Build and Upload CSPM Org Templates - run: make ci-org - working-directory: modules/foundational - env: - S3_BUCKET: cf-templates-cloudvision-ci - S3_PREFIX: pr/${{ github.event.pull_request.number }} \ No newline at end of file + S3_PREFIX: pr/${{ github.event.pull_request.number }} \ No newline at end of file diff --git a/modules/foundational/Makefile b/modules/foundational/Makefile index c8a5520..58bc0a5 100644 --- a/modules/foundational/Makefile +++ b/modules/foundational/Makefile @@ -6,64 +6,32 @@ S3_PREFIX ?= "test" S3_REGION ?= "eu-west-1" # ireland SECURE_API_TOKEN ?= "" STACK_NAME = "ModularFoundationalTest" -STACK_NAME_ORG = "ModularFoundationalOrgTest" - -.PHONY: packaged-template.yaml -.PHONY: packaged-template-org.yaml +PARAM_NAME_SUFFIX ?= "deadbeef" +PARAM_IS_ORGANIZATIONAL ?= "false" +.PHONY: validate lint deploy test clean validate: - aws cloudformation validate-template --template-body file://./single.yaml - aws cloudformation validate-template --template-body file://./org.yaml + aws cloudformation validate-template --template-body file://./template.yaml lint: cfn-lint *.yaml -packaged-template.yaml: - aws s3 rm s3://$(S3_BUCKET)/modules/foundational/$(S3_PREFIX) --recursive - - aws cloudformation package \ - --region $(S3_REGION) \ - --template-file single.yaml \ - --s3-bucket $(S3_BUCKET) \ - --s3-prefix modules/foundational/$(S3_PREFIX) \ - --force-upload \ - --output-template-file packaged-template.yaml +publish: + aws s3 cp ./template.yaml s3://$(S3_BUCKET)/modules/foundational/$(S3_PREFIX)/template.yaml -test: packaged-template.yaml +deploy: aws cloudformation deploy \ --stack-name $(STACK_NAME) \ - --template-file packaged-template.yaml \ + --template-file template.yaml \ --capabilities "CAPABILITY_NAMED_IAM" "CAPABILITY_AUTO_EXPAND" \ --parameter-overrides \ - "SysdigSecureAPIToken=$(SECURE_API_TOKEN)" - -ci: packaged-template.yaml - aws s3 cp ./packaged-template.yaml s3://$(S3_BUCKET)/modules/foundational/$(S3_PREFIX)/single.yaml + "NameSuffix=$(PARAM_NAME_SUFFIX)" \ + "ExternalID=$(PARAM_EXTERNAL_ID)" \ + "TrustedIdentity=$(PARAM_TRUSTED_IDENTITY)" \ + "IsOrganizational=$(PARAM_IS_ORGANIZATIONAL)" \ + "OrganizationUnitIDs=$(PARAM_ORGANIZATION_UNIT_IDS)" clean: aws cloudformation delete-stack --stack-name $(STACK_NAME) -packaged-template-org.yaml: - aws s3 rm s3://$(S3_BUCKET)/modules/foundational/$(S3_PREFIX) --recursive - aws cloudformation package \ - --region $(S3_REGION) \ - --template-file org.yaml \ - --s3-bucket $(S3_BUCKET) \ - --s3-prefix modules/foundational/$(S3_PREFIX) \ - --force-upload \ - --output-template-file packaged-template-org.yaml - -test-org: packaged-template-org.yaml - aws cloudformation deploy \ - --stack-name $(STACK_NAME_ORG) \ - --template-file packaged-template-org.yaml \ - --capabilities "CAPABILITY_NAMED_IAM" "CAPABILITY_AUTO_EXPAND" \ - --parameter-overrides \ - "SysdigSecureAPIToken=$(SECURE_API_TOKEN)" - -ci-org: packaged-template-org.yaml - aws s3 cp ./packaged-template-org.yaml s3://$(S3_BUCKET)/modules/foundational/$(S3_PREFIX)/org.yaml - -clean-org: - aws cloudformation delete-stack --stack-name $(STACK_NAME_ORG) \ No newline at end of file diff --git a/modules/foundational/org.yaml b/modules/foundational/org.yaml deleted file mode 100644 index 82e957e..0000000 --- a/modules/foundational/org.yaml +++ /dev/null @@ -1,186 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: Sysdig Secure Foundational Organization Onboarding -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: "Sysdig Settings (Do not change)" - Parameters: - - NameSuffix - - ExternalID - - TrustedIdentity - - OrganizationUnitIDs - ParameterLabels: - NameSuffix: - default: "Name Suffix (do not edit)" - ExternalID: - default: "External ID (do not edit)" - TrustedIdentity: - default: "Trusted Identity (do not edit)" - OrganizationUnitIDs: - default: "Organization Unit IDs (do not edit)" - -Parameters: - NameSuffix: - Type: String - Description: Suffix to append to the resource name identifiers - AllowedPattern: "[0-9a-f]+" - MaxLength: 8 - MinLength: 4 - ExternalID: - Type: String - Description: Sysdig ExternalID required for the policy creation - TrustedIdentity: - Type: String - Description: Sysdig Trusted identity required for policy creation - OrganizationUnitIDs: - Type: String - Description: Organization Unit IDs to deploy - -Resources: - ConfigPostureRole: - Type: "AWS::IAM::Role" - Properties: - RoleName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - AWS: !Sub ${TrustedIdentity} - Action: "sts:AssumeRole" - Condition: - StringEquals: - sts:ExternalId: !Sub ${ExternalID} - ManagedPolicyArns: - - arn:aws:iam::aws:policy/SecurityAudit - Policies: - - PolicyName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Action: "elasticfilesystem:DescribeAccessPoints" - Resource: "*" - - Effect: "Allow" - Action: - - "waf-regional:ListRules" - - "waf-regional:ListRuleGroups" - Resource: - - "arn:aws:waf-regional:*:*:rule/*" - - "arn:aws:waf-regional:*:*:rulegroup/*" - - Effect: "Allow" - Action: "macie2:ListClassificationJobs" - Resource: "*" - - Effect: "Allow" - Action: - - "lambda:GetRuntimeManagementConfig" - - "lambda:GetFunction" - Resource: "*" - - Effect: "Allow" - Action: "account:GetContactInformation" - Resource: "*" - - FoundationalStackSet: - Type: AWS::CloudFormation::StackSet - Properties: - StackSetName: AgentLessRoleStackSet - Description: Create a Role in all regions - PermissionModel: SERVICE_MANAGED - Capabilities: - - "CAPABILITY_NAMED_IAM" - AutoDeployment: - Enabled: true - RetainStacksOnAccountRemoval: false - ManagedExecution: - Active: true - Parameters: - - ParameterKey: NameSuffix - ParameterValue: !Ref NameSuffix - - ParameterKey: TrustedIdentity - ParameterValue: !Ref TrustedIdentity - - ParameterKey: ExternalID - ParameterValue: !Ref ExternalID - StackInstancesGroup: - - DeploymentTargets: - OrganizationalUnitIds: !Split [ ',', !Ref OrganizationUnitIDs] - Regions: - - !Ref "AWS::Region" - TemplateBody: | - AWSTemplateFormatVersion: "2010-09-09" - Description: IAM Role for Agentless - Parameters: - NameSuffix: - Type: String - Description: Suffix to append to the resource name identifiers - AllowedPattern: "[0-9a-f]+" - MaxLength: 8 - MinLength: 4 - TrustedIdentity: - Type: String - Description: Trusted identity - ExternalID: - Type: String - Description: external ID - - Resources: - ConfigPostureRole: - Type: "AWS::IAM::Role" - Properties: - RoleName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - AWS: !Sub ${TrustedIdentity} - Action: "sts:AssumeRole" - Condition: - StringEquals: - sts:ExternalId: !Sub ${ExternalID} - ManagedPolicyArns: - - arn:aws:iam::aws:policy/SecurityAudit - Policies: - - PolicyName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Action: "elasticfilesystem:DescribeAccessPoints" - Resource: "*" - - Effect: "Allow" - Action: - - "waf-regional:ListRules" - - "waf-regional:ListRuleGroups" - Resource: - - "arn:aws:waf-regional:*:*:rule/*" - - "arn:aws:waf-regional:*:*:rulegroup/*" - - Effect: "Allow" - Action: "macie2:ListClassificationJobs" - Resource: "*" - - Effect: "Allow" - Action: - - "lambda:GetRuntimeManagementConfig" - - "lambda:GetFunction" - Resource: "*" - - Effect: "Allow" - Action: "account:GetContactInformation" - Resource: "*" - - OnboardingRole: - Type: "AWS::IAM::Role" - Properties: - RoleName: !Join ["-", ["sysdig-secure", onboarding, !Ref NameSuffix]] - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - AWS: !Ref TrustedIdentity - Action: "sts:AssumeRole" - Condition: - StringEquals: - sts:ExternalId: !Ref ExternalID - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AWSAccountManagementReadOnlyAccess - - arn:aws:iam::aws:policy/AWSOrganizationsReadOnlyAccess \ No newline at end of file diff --git a/modules/foundational/single.yaml b/modules/foundational/single.yaml deleted file mode 100644 index 07237de..0000000 --- a/modules/foundational/single.yaml +++ /dev/null @@ -1,99 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: Sysdig Secure Foundational Onboarding - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: "Sysdig Settings (Do not change)" - Parameters: - - NameSuffix - - ExternalID - - TrustedIdentity - ParameterLabels: - NameSuffix: - default: "Name Suffix (do not edit)" - ExternalID: - default: "External ID (do not edit)" - TrustedIdentity: - default: "Trusted Identity (do not edit)" - -Parameters: - NameSuffix: - Type: String - Description: Suffix to append to the resource name identifiers - AllowedPattern: "[0-9a-f]+" - MaxLength: 8 - MinLength: 4 - ExternalID: - Type: String - Description: Sysdig generated token that proves you own this account - TrustedIdentity: - Type: String - Description: The Role in Sysdig's AWS Account with permissions to your account - -Resources: - ConfigPostureRole: - Type: "AWS::IAM::Role" - Properties: - RoleName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - AWS: !Ref TrustedIdentity - Action: "sts:AssumeRole" - Condition: - StringEquals: - sts:ExternalId: !Ref ExternalID - ManagedPolicyArns: - - arn:aws:iam::aws:policy/SecurityAudit - Policies: - - PolicyName: !Join ["-", ["sysdig-secure", !Ref NameSuffix]] - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Action: "elasticfilesystem:DescribeAccessPoints" - Resource: "*" - - Effect: "Allow" - Action: - - "waf-regional:ListRules" - - "waf-regional:ListRuleGroups" - Resource: - - "arn:aws:waf-regional:*:*:rule/*" - - "arn:aws:waf-regional:*:*:rulegroup/*" - - Effect: "Allow" - Action: "macie2:ListClassificationJobs" - Resource: "*" - - Effect: "Allow" - Action: - - "lambda:GetRuntimeManagementConfig" - - "lambda:GetFunction" - Resource: "*" - - Effect: "Allow" - Action: "account:GetContactInformation" - Resource: "*" - - OnboardingRole: - Type: "AWS::IAM::Role" - Properties: - RoleName: !Join ["-", ["sysdig-secure", onboarding, !Ref NameSuffix]] - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - AWS: !Ref TrustedIdentity - Action: "sts:AssumeRole" - Condition: - StringEquals: - sts:ExternalId: !Ref ExternalID - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AWSAccountManagementReadOnlyAccess - -Outputs: - RoleARN: - Description: ARN of the role created - Value: !Sub ${ConfigPostureRole.Arn} \ No newline at end of file diff --git a/modules/foundational/template.yaml b/modules/foundational/template.yaml new file mode 100644 index 0000000..28a9375 --- /dev/null +++ b/modules/foundational/template.yaml @@ -0,0 +1,265 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Sysdig Secure Onboarding +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Sysdig Assigned Settings (Do not change) + Parameters: + - NameSuffix + - ExternalID + - TrustedIdentity + - IsOrganizational + - OrganizationalUnitIDs + ParameterLabels: + NameSuffix: + default: Name Suffix + ExternalID: + default: External ID + TrustedIdentity: + default: Trusted Identity + IsOrganizational: + default: Is Organizational + OrganizationalUnitIDs: + default: Organizational Unit IDs +Parameters: + NameSuffix: + Type: String + Description: Suffix to append to the resource name identifiers + AllowedPattern: '[0-9a-z]+' + MaxLength: 8 + MinLength: 4 + ExternalID: + Type: String + Description: Sysdig generated token that proves you own this account + TrustedIdentity: + Type: String + Description: The Role in Sysdig's AWS Account with permissions to your account + IsOrganizational: + Type: String + Description: Install into an organization + Default: 'false' + AllowedValues: + - 'true' + - 'false' + OrganizationalUnitIDs: + Type: CommaDelimitedList + Description: Comma separated list of organizational unit IDs to deploy +Conditions: + IsOrganizational: + Fn::Equals: + - Ref: IsOrganizational + - 'true' +Resources: + ConfigPostureRole: + Type: AWS::IAM::Role + Properties: + RoleName: + Fn::Join: + - '-' + - - sysdig-secure + - Ref: NameSuffix + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + AWS: + Ref: TrustedIdentity + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: + Ref: ExternalID + ManagedPolicyArns: + - arn:aws:iam::aws:policy/SecurityAudit + Policies: + - PolicyName: + Fn::Join: + - '-' + - - sysdig-secure + - Ref: NameSuffix + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: elasticfilesystem:DescribeAccessPoints + Resource: '*' + - Effect: Allow + Action: + - waf-regional:ListRules + - waf-regional:ListRuleGroups + Resource: + - arn:aws:waf-regional:*:*:rule/* + - arn:aws:waf-regional:*:*:rulegroup/* + - Effect: Allow + Action: macie2:ListClassificationJobs + Resource: '*' + - Effect: Allow + Action: + - lambda:GetRuntimeManagementConfig + - lambda:GetFunction + Resource: '*' + - Effect: Allow + Action: account:GetContactInformation + Resource: '*' + OnboardingRole: + Type: AWS::IAM::Role + Properties: + RoleName: + Fn::Join: + - '-' + - - sysdig-secure + - onboarding + - Ref: NameSuffix + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + AWS: + Ref: TrustedIdentity + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: + Ref: ExternalID + ManagedPolicyArns: + Fn::If: + - IsOrganizational + - - arn:aws:iam::aws:policy/AWSAccountManagementReadOnlyAccess + - arn:aws:iam::aws:policy/AWSOrganizationsReadOnlyAccess + - - arn:aws:iam::aws:policy/AWSAccountManagementReadOnlyAccess + OrganizationStackSet: + Type: AWS::CloudFormation::StackSet + Condition: IsOrganizational + Properties: + StackSetName: Sysdig-Secure-Organization + Description: Creates IAM roles within an AWS organization + PermissionModel: SERVICE_MANAGED + Capabilities: + - CAPABILITY_NAMED_IAM + AutoDeployment: + Enabled: true + RetainStacksOnAccountRemoval: false + ManagedExecution: + Active: true + Parameters: + - ParameterKey: NameSuffix + ParameterValue: + Ref: NameSuffix + - ParameterKey: TrustedIdentity + ParameterValue: + Ref: TrustedIdentity + - ParameterKey: ExternalID + ParameterValue: + Ref: ExternalID + StackInstancesGroup: + - DeploymentTargets: + OrganizationalUnitIds: + Fn::Split: + - ',' + - Ref: OrganizationalUnitIDs + Regions: + - Ref: AWS::Region + TemplateBody: | + AWSTemplateFormatVersion: "2010-09-09" + Description: IAM Role for Agentless + Parameters: + NameSuffix: + Type: String + Description: Suffix to append to the resource name identifiers + AllowedPattern: "[0-9a-z]+" + MaxLength: 8 + MinLength: 4 + TrustedIdentity: + Type: String + Description: Trusted identity + ExternalID: + Type: String + Description: external ID + + Resources: + ConfigPostureRole: + Type: "AWS::IAM::Role" + Properties: + RoleName: + Fn::Join: + - "-" + - - sysdig-secure + - !Ref NameSuffix + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Principal: + AWS: !Sub ${TrustedIdentity} + Action: "sts:AssumeRole" + Condition: + StringEquals: + sts:ExternalId: !Sub ${ExternalID} + ManagedPolicyArns: + - arn:aws:iam::aws:policy/SecurityAudit + Policies: + - PolicyName: + Fn::Join: + - "-" + - - sysdig-secure + - !Ref NameSuffix + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Action: "elasticfilesystem:DescribeAccessPoints" + Resource: "*" + - Effect: "Allow" + Action: + - "waf-regional:ListRules" + - "waf-regional:ListRuleGroups" + Resource: + - "arn:aws:waf-regional:*:*:rule/*" + - "arn:aws:waf-regional:*:*:rulegroup/*" + - Effect: "Allow" + Action: "macie2:ListClassificationJobs" + Resource: "*" + - Effect: "Allow" + Action: + - "lambda:GetRuntimeManagementConfig" + - "lambda:GetFunction" + Resource: "*" + - Effect: "Allow" + Action: "account:GetContactInformation" + Resource: "*" + OnboardingRole: + Type: AWS::IAM::Role + Properties: + RoleName: + Fn::Join: + - '-' + - - sysdig-secure + - onboarding + - Ref: NameSuffix + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + AWS: + Ref: TrustedIdentity + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: + Ref: ExternalID + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AWSAccountManagementReadOnlyAccess + +Outputs: + ConfigPostureRoleARN: + Description: ARN of the config posture role + Value: + Fn::Sub: ${ConfigPostureRole.Arn} + OnboardingRoleARN: + Description: ARN of the onboarding role + Value: + Fn::Sub: ${OnboardingRole.Arn}