Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudformation access key #2123

Merged
merged 12 commits into from
Apr 16, 2024
67 changes: 67 additions & 0 deletions .github/workflows/cloudformation-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ on:
paths:
- deploy/cloudformation/*.yml
- .github/workflows/cloudformation-ci.yml
push:
branches:
- main
- "[0-9]+.[0-9]+"
paths:
- deploy/cloudformation/*.yml
- .github/workflows/cloudformation-ci.yml

env:
WORKING_DIR: deploy/test-environments
Expand Down Expand Up @@ -115,3 +122,63 @@ jobs:
terraform destroy --auto-approve -target="module.ec_deployment" -target="module.ec_project"
aws cloudformation delete-stack --stack-name ${{ env.CNVM_STACK_NAME }}
aws cloudformation wait stack-delete-complete --stack-name ${{ env.CNVM_STACK_NAME }}


Deploy-CloudFormation-DirectKeys:
name: "Deploy CloudFormation DirectKeys"
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Hermit Environment
uses: ./.github/actions/hermit
with:
init-tools: 'true'

- name: Set up unique deployment names
run: |
suffix="$(date +%s | tail -c 3)"
echo "DIRECT_KEY_STACK_NAME=direct-key-stack-pr${{ github.event.number }}-$suffix" >> $GITHUB_ENV

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_TEST_ACC }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_TEST_ACC }}
aws-region: "eu-west-1"

- name: Deploy CloudFormation stack
env:
CF_FILE: 'deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml'
run: |
aws cloudformation validate-template --template-body file://${{ env.CF_FILE }}
aws cloudformation create-stack --stack-name ${{ env.DIRECT_KEY_STACK_NAME }} --template-body file://${{ env.CF_FILE }} --capabilities CAPABILITY_NAMED_IAM
aws cloudformation wait stack-create-complete --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}

- name: Get Direct Keys
id: direct-keys
shell: bash
run: |
BODY="$(aws cloudformation describe-stacks --stack-name ${{ env.DIRECT_KEY_STACK_NAME }} --query 'Stacks[0].Outputs' --output json)"
NEW_ACCESS_KEY_ID="$(echo "${BODY}" | jq -r '.[] | select(.OutputKey | test("AccessKeyId")) | .OutputValue')"
echo "::add-mask::$NEW_ACCESS_KEY_ID"
NEW_SECRET_ACCESS_KEY="$(echo "${BODY}" | jq -r '.[] | select(.OutputKey | test("SecretAccessKey")) | .OutputValue')"
echo "::add-mask::$NEW_SECRET_ACCESS_KEY"
echo "NEW_ACCESS_KEY_ID=${NEW_ACCESS_KEY_ID}" >> $GITHUB_OUTPUT
echo "NEW_SECRET_ACCESS_KEY=${NEW_SECRET_ACCESS_KEY}" >> $GITHUB_OUTPUT

- name: Run AWS integration tests
uses: ./.github/actions/aws-ci
with:
elk-version: ${{ env.ELK_VERSION }}
aws-access-key-id: ${{ steps.direct-keys.outputs.NEW_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ steps.direct-keys.outputs.NEW_SECRET_ACCESS_KEY }}
aws-account-type: single-account

- name: Cleanup Environment
if: always()
run: |
aws cloudformation delete-stack --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}
aws cloudformation wait stack-delete-complete --stack-name ${{ env.DIRECT_KEY_STACK_NAME }}
2 changes: 1 addition & 1 deletion deploy/aws/cloudbeat-aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cloudbeat:
credentials:
access_key_id: ${AWS_ACCESS_KEY_ID:""}
secret_access_key: ${AWS_SECRET_ACCESS_KEY:""}
account_type: ${AWS_ACCOUNT_TYPE:""}
account_type: ${AWS_ACCOUNT_TYPE:""}
type: cloudbeat/cis_aws
# Defines how often an event is sent to the output
period: 30s
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
AWSTemplateFormatVersion: "2010-09-09"

Description: Creates elastic-agent cspm user, role, and access key, and outputs the access key

Parameters:
OrganizationalUnitIds:
Description: |
Comma-separated list of organizational units to deploy the IAM roles to.
Specify the unique IDs of the organizational units where the roles should be deployed.
Example: ou-abc123,ou-def456,ou-ghi789
Type: CommaDelimitedList
AllowedPattern: ^(ou-[0-9a-z]{4,32}-[a-z0-9]{8,32}|r-[0-9a-z]{4,32})$

ScanManagementAccount:
Description: |
When set to "Yes", the Management Account resources will be scanned,
regardless of selected Organizational Unit IDs. Likewise, when set to
"No", the Management Account resources will not be scanned, even if
the Management Account belongs to a selected Organizational Unit.
Type: String
AllowedValues:
- "Yes"
- "No"
Default: "Yes"
ConstraintDescription: Must specify "Yes" or "No"

Conditions:
ScanManagementAccountEnabled: !Equals
- !Ref ScanManagementAccount
- "Yes"

Resources:
ElasticCSPMUser:
Type: AWS::IAM::User
Properties:
UserName: !Join
- '-'
- - elasticagent-user-cspm
- !Select
- 2
- !Split
- /
- !Ref AWS::StackId
Path: /

CloudbeatRootRole:
Type: AWS::IAM::Role
Properties:
RoleName: cloudbeat-root
Description: Role that cloudbeat uses to assume roles in other accounts
Tags:
- Key: cloudbeat_scan_management_account
Value: !Ref ScanManagementAccount
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !Ref AWS::AccountId
Action:
- sts:AssumeRole
- Effect: Allow
Principal:
AWS: !GetAtt ElasticCSPMUser.Arn
Action:
- sts:AssumeRole
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: cloudbeat-root-permissions
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- iam:GetRole
- iam:ListAccountAliases
- iam:ListGroup
- iam:ListRoles
- iam:ListUsers
Resource: '*'
- Effect: Allow
Action:
- organizations:List*
- organizations:Describe*
Resource: '*'
- Effect: Allow
Action:
- sts:AssumeRole
Resource: '*'

CloudbeatRoleStackSet:
Type: AWS::CloudFormation::StackSet
Properties:
StackSetName: cloudbeat-role-stackset
Description: StackSet for deploying the cloudbeat-securityaudit IAM role to member accounts in the specified organizational units.
AutoDeployment:
Enabled: true
RetainStacksOnAccountRemoval: false
Capabilities:
- CAPABILITY_NAMED_IAM
ManagedExecution:
Active: true
Parameters:
- ParameterKey: RootRoleArn
ParameterValue: !GetAtt CloudbeatRootRole.Arn
PermissionModel: SERVICE_MANAGED
StackInstancesGroup:
- DeploymentTargets:
OrganizationalUnitIds: !Ref OrganizationalUnitIds
Regions:
- !Ref AWS::Region
TemplateBody: |
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates IAM roles needed for multi-account access
Parameters:
RootRoleArn:
Type: String
Resources:
CloudbeatMemberRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: cloudbeat-securityaudit
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Ref RootRoleArn
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit

CloudbeatManagementAccountAuditRole:
Type: AWS::IAM::Role
Properties:
RoleName: cloudbeat-securityaudit
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !GetAtt CloudbeatRootRole.Arn
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
Condition: ScanManagementAccountEnabled

ElasticCSPMAccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref ElasticCSPMUser

Outputs:
AccessKeyId:
Description: Access Key ID
Value: !Ref ElasticCSPMAccessKey
Export:
Name: AccessKeyId

SecretAccessKey:
Description: Secret Access Key
Value: !GetAtt ElasticCSPMAccessKey.SecretAccessKey
Export:
Name: SecretAccessKey
39 changes: 39 additions & 0 deletions deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
AWSTemplateFormatVersion: "2010-09-09"

Description: Creates elastic-agent cspm user, role, and access key, and outputs the access key

Parameters: {}

Resources:
ElasticCSPMUser:
Type: AWS::IAM::User
Properties:
UserName: !Join
- '-'
- - elasticagent-user-cspm
- !Select
- 2
- !Split
- /
- !Ref AWS::StackId
ManagedPolicyArns:
- arn:aws:iam::aws:policy/SecurityAudit
Path: /

ElasticCSPMAccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref ElasticCSPMUser

Outputs:
AccessKeyId:
Description: Access Key ID
Value: !Ref ElasticCSPMAccessKey
Export:
Name: AccessKeyId

SecretAccessKey:
Description: Secret Access Key
Value: !GetAtt ElasticCSPMAccessKey.SecretAccessKey
Export:
Name: SecretAccessKey
2 changes: 2 additions & 0 deletions scripts/publish_cft.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ version=$(grep defaultBeatVersion version/version.go | cut -f2 -d "\"")
upload_file deploy/cloudformation/elastic-agent-ec2-cnvm.yml "cloudformation-cnvm" "$version"
upload_file deploy/cloudformation/elastic-agent-ec2-cspm.yml "cloudformation-cspm-single-account" "$version"
upload_file deploy/cloudformation/elastic-agent-ec2-cspm-organization.yml "cloudformation-cspm-organization-account" "$version"
upload_file deploy/cloudformation/elastic-agent-direct-access-key-cspm.yml "cloudformation-cspm-direct-access-key-single-account" "$version"
upload_file deploy/cloudformation/elastic-agent-direct-access-key-cspm-organization.yml "cloudformation-cspm-direct-access-key-organization-account" "$version"
Loading