diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml new file mode 100644 index 0000000..b9cd4a9 --- /dev/null +++ b/.github/workflows/promote.yml @@ -0,0 +1,72 @@ +name: promote + +on: + workflow_dispatch: + inputs: + release_version: + description: 'The release version, e.g. 5.0.0.' + type: string + required: true + + rc_number: + description: 'The release candidate number to promote, e.g. 1.' + type: string + required: true + +jobs: + promote: + env: + RC_NAME: ${{ inputs.release_version }}-rc${{ inputs.rc_tag }} + name: Promote + runs-on: ubuntu-latest + steps: + - name: Verify inputs + shell: bash + run: | + if [[ ! "${{ inputs.release_version }}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + echo "The provided release version is not valid" + exit 1 + fi + + if [[ ! "${{ inputs.rc_number }}" =~ ^([0-9])+$ ]]; then + echo "The provided rc tag is not valid" + exit 1 + fi + + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Promote RC Tag + shell: bash + run: | + if ! git rev-parse "${RC_NAME}" &>/dev/null; then + echo "The RC Tag ${RC_NAME} does not exist" + exit 1 + fi + + git fetch --tags + git tag "${{ inputs.release_version }}" "${RC_NAME}" + git push -u origin "${{ inputs.release_version }}" + + - name: Get resources from RC + shell: bash + run: | + rm -f cloudformation.zip + rm -f checksums.txt + curl -L "https://github.com/${{ github.repository }}/releases/download/${RC_NAME}/cloudformation.zip" > cloudformation.zip + curl -L "https://github.com/${{ github.repository }}/releases/download/${RC_NAME}/checksums.txt" > checksums.txt + + - name: Create release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + files: | + cloudformation.zip + checksums.txt + name: ${{ inputs.release_version }} + tag_name: ${{ inputs.release_version }} + prerelease: false + make_latest: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bea96f9..6669c7b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,45 +1,96 @@ -name: Release agent-kilt +name: release on: - push: - tags: - - 'v*' + workflow_dispatch: + inputs: + release_version: + description: 'The release version, e.g. 5.0.0.' + type: string + required: true -env: - GO_VERSION: 1.21.x + rc_number: + description: 'The release candidate number, e.g. 1.' + type: string + required: true + + serverless_agent_version: + description: 'The version of the serverless-agent to be referenced by this release, e.g., 4.0.0. It will use the same version as the release if not specified.' + type: string + required: false jobs: release: + env: + RC_NAME: ${{ inputs.release_version }}-rc${{ inputs.rc_number }} name: Release runs-on: ubuntu-latest steps: - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: ${{ env.GO_VERSION }} - id: go + - name: Verify inputs + shell: bash + run: | + if [[ ! "${{ inputs.release_version }}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + echo "The provided release version is not valid" + exit 1 + fi + + if [[ ! "${{ inputs.rc_number }}" =~ ^([0-9])+$ ]]; then + echo "The provided rc tag is not valid" + exit 1 + fi + + docker pull "quay.io/sysdig/workload-agent:${{ inputs.serverless_agent_version }}" &> /dev/null + exit_code=$? + if [[ $exit_code -ne 0 ]]; then + echo "The provided serverless_agent_version does not exists." + exit 1 + fi - name: Checkout Code uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Build agent-kilt handler + - name: Push RC tag + shell: bash + run: | + git fetch --tags + if git rev-parse "${RC_NAME}" &> /dev/null; then + echo "The tag ${RC_NAME} already exists" + exit 1 + fi + git tag "${RC_NAME}" + git push -u origin "${RC_NAME}" + + - name: Prepare dist package + shell: bash + run: | + rm -rf dist + mkdir -p dist/provisioning/cloudformation + + - name: Add versioned CloudFormation templates + env: + RELEASE_VERSION: ${{ inputs.release_version }} + SERVERLESS_AGENT_VERSION: ${{ inputs.serverless_agent_version || inputs.release_version }} + shell: bash run: | - make -C runtimes/cloudformation clean cmd/handler/handler + script="s/(dev)/${RELEASE_VERSION}/g; s/agent:latest/agent:${SERVERLESS_AGENT_VERSION}/g" + sed "$script" provisioning/cloudformation/orchestrator-agent.yaml > dist/provisioning/cloudformation/orchestrator-agent.yaml + sed "$script" provisioning/cloudformation/instrumentation.yaml > dist/provisioning/cloudformation/instrumentation.yaml - - name: Archive build + - name: Create prerelease attachments + shell: bash run: | - zip -j agent-kilt.zip runtimes/cloudformation/cmd/handler/handler - sha256sum agent-kilt.zip > checksums.txt + pushd dist/provisioning; zip -r ../../cloudformation.zip .; popd + sha256sum cloudformation.zip > checksums.txt - - name: Create GitHub Release - id: create_release - uses: softprops/action-gh-release@v1 + - name: Create prerelease + uses: softprops/action-gh-release@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: files: | - agent-kilt.zip + cloudformation.zip checksums.txt - tag_name: ${{ github.ref }} + name: ${RC_NAME} + tag_name: ${RC_NAME} + prerelease: true diff --git a/provisioning/cloudformation/instrumentation.yaml b/provisioning/cloudformation/instrumentation.yaml new file mode 100644 index 0000000..bf1238d --- /dev/null +++ b/provisioning/cloudformation/instrumentation.yaml @@ -0,0 +1,232 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Description: Sysdig Serverless Instrumentation Stack (dev) + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Orchestrator Agent Settings + Parameters: + - SysdigOrchestratorAgentHost + - SysdigOrchestratorAgentPort + - Label: + default: Instrumentation Settings + Parameters: + - SysdigMacroName + - SysdigInstrumentationLogLevel + - SysdigServerlessPatcherImage + - SysdigWorkloadAgentImage + - Label: + default: Instrumentation Resource Allocation + Parameters: + - SysdigPriority + - SysdigSidecarEssential + - SysdigSidecarCpu + - SysdigSidecarMemoryLimit + - SysdigSidecarMemoryReservation + ParameterLabels: + # Orchestrator Settings + SysdigOrchestratorAgentHost: + default: Orchestrator Agent Host + SysdigOrchestratorAgentPort: + default: Orchestartor Agent Port + # Instrumentation Settings + SysdigMacroName: + default: Macro Name + SysdigInstrumentationLogLevel: + default: Sysdig Instrumentation Logging Level + SysdigServerlessPatcherImage: + default: Sysdig Serverless Patcher Image + SysdigWorkloadAgentImage: + default: Sysdig Workload Agent Image + # Instrumentation Resource Allocation + SysdigPriority: + default: Instrumentation priority + SysdigSidecarEssential: + default: Sidecar Essential Flag + SysdigSidecarCpu: + default: Sidecar CPU Units + SysdigSidecarMemoryLimit: + default: Sidecar Memory Limit + SysdigSidecarMemoryReservation: + default: Sidecar Memory Reservation + +Parameters: + # Orchestrator Agent Settings + SysdigOrchestratorAgentHost: + Type: String + + SysdigOrchestratorAgentPort: + Type: String + Default: "6667" + AllowedPattern: ^[0-9]+$ + ConstraintDescription: Orchestrator Agent Port can include only numbers + + # Instrumentation Settings + SysdigMacroName: + Type: String + Description: Must be unique within your account + AllowedPattern: ^[A-Za-z0-9]+$ + Default: "SysdigMacro" + ConstraintDescription: Macro Name can include only letters and numbers + + SysdigInstrumentationLogLevel: + Type: String + Default: "info" + AllowedValues: + - "silent" + - "error" + - "warning" + - "info" + - "debug" + - "trace" + + SysdigServerlessPatcherImage: + Type: String + Description: Will patch your template to install the Sysdig Workload Agent - Must be hosted on an ECR private registry + Default: "quay.io/sysdig/serverless-patcher:latest" + + SysdigWorkloadAgentImage: + Type: String + Description: The Sysdig Agent that will secure your workload + Default: "quay.io/sysdig/workload-agent:latest" + + SysdigPriority: + Type: String + Description: "Instrumentation priority. If set to security, the instrumentation will prevent an unsecured workload from running." + Default: "availability" + AllowedValues: + - "security" + - "availability" + + SysdigSidecarEssential: + Type: String + Description: "If true, the sidecar container will be marked as essential. If false, the sidecar container will be marked as non-essential. If set to auto, will follow the selected priority (true for security, false for availability)" + Default: "auto" + AllowedValues: + - "auto" + - "true" + - "false" + + SysdigSidecarCpu: + Type: String + Description: "The number of cpu units to reserve for the sidecar container. This is optional, but if specified, it must be a positive integer." + Default: "" + AllowedPattern: ^[0-9]*$ + ConstraintDescription: Sidecar CPU can include only numbers + + SysdigSidecarMemoryLimit: + Type: String + Description: "The amount of memory (in MiB) to limit the sidecar container to. This is optional, but if specified, it must be a positive integer." + Default: "" + AllowedPattern: ^[0-9]*$ + ConstraintDescription: Sidecar Memory Limit can include only numbers + + SysdigSidecarMemoryReservation: + Type: String + Description: "The amount of memory (in MiB) to reserve for the sidecar container. This is optional, but if specified, it must be a positive integer." + Default: "" + AllowedPattern: ^[0-9]*$ + ConstraintDescription: Sidecar Memory Reservation can include only numbers + +Mappings: + Sysdig: + Collector: + SysdigAccessKey: "" + SysdigCollectorHost: "" + SysdigCollectorPort: "" + Agent: + NiceValueIncrement: "" + SidecarMode: "" + Kilt: + Mode: + OptIn: "" + Customization: + Definition: "" + DefinitionType: "" + RecipeConfiguration: "" + +Conditions: + IsSysdigDirectConnection: !And + - !Not [!Equals [!FindInMap [Sysdig, Collector, SysdigAccessKey], "" ]] + - !Not [!Equals [!FindInMap [Sysdig, Collector, SysdigCollectorHost], "" ]] + - !Not [!Equals [!FindInMap [Sysdig, Collector, SysdigCollectorPort], "" ]] + IsKiltModeOptIn: !Equals [!FindInMap [Kilt, Mode, OptIn], "true"] + IsKiltCustomDefinition: !And + - !Not [!Equals [!FindInMap [Kilt, Customization, Definition], ""]] + - !Not [!Equals [!FindInMap [Kilt, Customization, DefinitionType], ""]] + IsKiltCustomRecipeConfiguration: !Not [ !Equals [!FindInMap [Kilt, Customization, RecipeConfiguration], ""]] + DoSetNiceValueIncrement: !Not [ !Equals [!FindInMap [Sysdig, Agent, NiceValueIncrement], ""]] + DoSetSidecarMode: !Not [ !Equals [!FindInMap [Sysdig, Agent, SidecarMode], ""]] + IsSidecarEssentialAuto: !Equals [!Ref SysdigSidecarEssential, "auto"] + IsPrioritySecurity: !Equals [!Ref SysdigPriority, "security"] + +Outputs: + SysdigTransformationMacro: + Description: Add this transformation macro at the root level of your template + Value: !Sub 'Transform: ["${SysdigMacroName}"]' + +Resources: + SysdigLogGroup: + Type: AWS::Logs::LogGroup + Properties: + RetentionInDays: 365 + + ServerlessPatcherRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + ManagedPolicyArns: + - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + + ServerlessPatcherLambda: + Type: AWS::Lambda::Function + Properties: + PackageType: Image + Role: !GetAtt ServerlessPatcherRole.Arn + Code: + ImageUri: !Ref SysdigServerlessPatcherImage + Environment: + Variables: + # Sysdig Orchestrator Agent + SYSDIG_ORCHESTRATOR_HOST: !Ref SysdigOrchestratorAgentHost + SYSDIG_ORCHESTRATOR_PORT: !Ref SysdigOrchestratorAgentPort + # Sysdig Instrumentation + SYSDIG_WORKLOAD_AGENT_IMAGE: !Ref SysdigWorkloadAgentImage + SYSDIG_LOGGING: !Ref SysdigInstrumentationLogLevel + SYSDIG_PRIORITY: !Ref SysdigPriority + KILT_LOG_GROUP: !Ref SysdigLogGroup + # Sysdig Collector + SYSDIG_ACCESS_KEY: !If [IsSysdigDirectConnection, !FindInMap [Sysdig, Collector, SysdigAccessKey], !Ref AWS::NoValue] + SYSDIG_COLLECTOR_HOST: !If [IsSysdigDirectConnection, !FindInMap [Sysdig, Collector, SysdigCollectorHost], !Ref AWS::NoValue] + SYSDIG_COLLECTOR_PORT: !If [IsSysdigDirectConnection, !FindInMap [Sysdig, Collector, SysdigCollectorPort], !Ref AWS::NoValue] + # Sysdig Agent Nice Value Increment + SYSDIG_AGENT_NICE_VALUE_INCREMENT: !If [DoSetNiceValueIncrement, !FindInMap [Sysdig, Agent, NiceValueIncrement], !Ref AWS::NoValue] + # Sidecar mode + SYSDIG_SIDECAR_MODE: !If [DoSetSidecarMode, !FindInMap [Sysdig, Agent, SidecarMode], "auto"] + # Kilt OptIn Mode + KILT_OPT_IN: !If [IsKiltModeOptIn, "YES", !Ref AWS::NoValue] + # Kilt Definition/Recipe Customization + KILT_DEFINITION: !If [IsKiltCustomDefinition, !FindInMap [Kilt, Customization, Definition], !Ref AWS::NoValue] + KILT_DEFINITION_TYPE: !If [IsKiltCustomDefinition, !FindInMap [Kilt, Customization, DefinitionType], !Ref AWS::NoValue] + KILT_RECIPE_CONFIG: !If [IsKiltCustomRecipeConfiguration, !FindInMap [Kilt, Customization, RecipeConfiguration], !Ref AWS::NoValue] + KILT_SIDECAR_ESSENTIAL: !If [ IsSidecarEssentialAuto, !If [ IsPrioritySecurity, "true", "false"], !Ref SysdigSidecarEssential ] + KILT_SIDECAR_CPU: !Ref SysdigSidecarCpu + KILT_SIDECAR_MEMORY_LIMIT: !Ref SysdigSidecarMemoryLimit + KILT_SIDECAR_MEMORY_RESERVATION: !Ref SysdigSidecarMemoryReservation + + ServerlessPatcherMacro: + Type: AWS::CloudFormation::Macro + Properties: + Name: !Ref SysdigMacroName + Description: Applies Sysdig instrumentation to Fargate ECS Tasks + FunctionName: !GetAtt ServerlessPatcherLambda.Arn diff --git a/provisioning/cloudformation/orchestrator-agent.yaml b/provisioning/cloudformation/orchestrator-agent.yaml new file mode 100644 index 0000000..09f4d16 --- /dev/null +++ b/provisioning/cloudformation/orchestrator-agent.yaml @@ -0,0 +1,547 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Description: Sysdig Serverless Orchestrator Agent (dev) + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Sysdig Settings + Parameters: + - SysdigAccessKey + - SysdigCollectorHost + - SysdigCollectorPort + - Label: + default: Network Settings + Parameters: + - VPC + - SubnetA + - SubnetB + - NetworkType + - Label: + default: Advanced Settings + Parameters: + - SysdigAgentTags + - SysdigOrchestratorAgentImage + - SysdigCheckCollectorCertificate + - SysdigOrchestratorAgentPort + - Label: + default: Autoscaling + Parameters: + - TargetMetric + - TargetValue + - MaxCapacity + - ScaleInCooldown + - ScaleOutCooldown + ParameterLabels: + # Sysdig Settings + SysdigAccessKey: + default: Sysdig Access Key + SysdigCollectorHost: + default: Sysdig Collector Host + SysdigCollectorPort: + default: Sysdig Collector Port + # Network Settings + VPC: + default: VPC Id + SubnetA: + default: Subnet A + SubnetB: + default: Subnet B + NetworkType: + default: Network Type + # Advanced Settings + SysdigAgentTags: + default: Agent Tags + SysdigOrchestratorAgentImage: + default: Sysdig Orchestrator Agent Image + SysdigCheckCollectorCertificate: + default: Check Collector SSL Certificate + SysdigOrchestratorAgentPort: + default: Sysdig Orchestrator Agent Port + # Autoscaling + TargetMetric: + default: Target metric + TargetValue: + default: Target value + MaxCapacity: + default: Maximum capacity + ScaleInCooldown: + default: Scale-in cooldown (seconds) + ScaleOutCooldown: + default: Scale-out cooldown (seconds) + +Mappings: + # Orchestrator - Upload custom CA certificates + CACertificate: + Collector: + Type: "base64" + Value: "" + Path: "/ssl/collector_cert.pem" + HttpProxy: + Type: "base64" + Value: "" + Path: "/ssl/proxy_cert.pem" + + # Orchestrator - Advanced configuration options + Configuration: + Collector: + CACertificate: "" # /ssl/collector_cert.pem + HttpProxy: + ProxyHost: "" + ProxyPort: "" + ProxyUser: "" + ProxyPassword: "" # Cleartext or SecretsManager secret reference (arn:aws:secretsmanager:region:aws_account_id:secret:secret-name:json-key:version-stage:version-id)" + SSL: "" + SSLVerifyCertificate: "" + CACertificate: "" # /ssl/proxy_cert.pem + + # ECS Cluster - Configuration + Cluster: + Configuration: + ContainerInsights: "" # enabled | disabled + +Parameters: + # Sysdig Settings + SysdigAccessKey: + Type: String + Description: "Cleartext or SecretsManager secret reference (arn:aws:secretsmanager:region:aws_account_id:secret:secret-name:json-key:version-stage:version-id)" + + SysdigCollectorHost: + Type: String + Default: collector.sysdigcloud.com + + SysdigCollectorPort: + Type: String + Default: 6443 + AllowedPattern: ^[0-9]+$ + ConstraintDescription: Sysdig Collector Port must be a number + + # Network Settings + VPC: + Type: AWS::EC2::VPC::Id + Description: VPC where your service is deployed + + SubnetA: + Type: AWS::EC2::Subnet::Id + Description: A subnet that can access internet and is reachable by instrumented services + + SubnetB: + Type: AWS::EC2::Subnet::Id + Description: A subnet that can access internet and is reachable by instrumented services + + NetworkType: + Type: String + Description: Defines whether or not the task needs a public IP + AllowedValues: + - "Public Subnet" + - "Private Subnet" + + # Advanced Settings + SysdigAgentTags: + Type: String + Description: Enter a comma-separated list of tags (e.g. role:webserver,location:europe) + Default: "" + + SysdigOrchestratorAgentImage: + Type: String + Default: quay.io/sysdig/orchestrator-agent:latest + + SysdigCheckCollectorCertificate: + Type: String + Default: true + AllowedValues: + - true + - false + + SysdigOrchestratorAgentPort: + Type: String + Description: Port that the orchestrator and workload will use to communicate + Default: 6667 + AllowedPattern: ^[0-9]+$ + ConstraintDescription: Sysdig Orchestrator Agent Port must be a number + + # Autoscaling + TargetMetric: + Type: String + Default: "Disabled" + AllowedValues: + - "Disabled" + - "ECSServiceAverageCPUUtilization" + - "ECSServiceAverageMemoryUtilization" + + TargetValue: + Type: String + Description: "The target value for the chosen metric" + AllowedPattern: ^[0-9]+$ + ConstraintDescription: "The autoscaling target value must be a number" + Default: 0 + + MaxCapacity: + Type: String + Description: "The maximum capacity that you plan to scale out to" + AllowedPattern: ^[0-9]+$ + ConstraintDescription: "The autoscaling maximum capacity must be a number" + Default: 0 + + ScaleInCooldown: + Type: String + AllowedPattern: ^[0-9]+$ + Description: "The scaling policy will not decrease the capacity until previous scale-in cooldown period has expired" + ConstraintDescription: "The autoscaling scale-in cooldown must be a number" + Default: 0 + + ScaleOutCooldown: + Type: String + AllowedPattern: ^[0-9]+$ + Description: "The scaling policy will not increase the capacity again unless either a larger scale out is triggered or the cooldown period ends" + ConstraintDescription: "The autoscaling scale-out cooldown must be a number" + Default: 0 + +Conditions: + IsPublicSubnet: !Equals [!Ref NetworkType, "Public Subnet"] + + DoFetchSecretAccessKey: !Equals [!Select [0, !Split ["arn:aws:secretsmanager", !Ref SysdigAccessKey]], ""] + + DoUploadCollectorCACertificate: !Not [!Equals [!FindInMap [ CACertificate, Collector, Value ], ""] ] + + DoUploadHttpProxyCACertificate: !Not [!Equals [!FindInMap [ CACertificate, HttpProxy, Value ], ""] ] + + DoConfigureCollectorCACertificate: !Not [!Equals [!FindInMap [ Configuration, Collector, CACertificate ], ""] ] + + DoConfigureHttpProxy: !Not [!Equals [!FindInMap [ Configuration, HttpProxy, ProxyHost ], ""] ] + + IsProxyPasswordSecret: !And + - !Not [ !Equals [ !FindInMap [ Configuration, HttpProxy, ProxyPassword ], ""] ] + - !Equals [!Select [0, !Split ["arn:aws:secretsmanager", !FindInMap [ Configuration, HttpProxy, ProxyPassword ] ] ], ""] + + DoFetchSecretProxyPassword: !And + - !Condition DoConfigureHttpProxy + - !Condition IsProxyPasswordSecret + + DoUseCleartextProxyPassword: !And + - !Condition DoConfigureHttpProxy + - !Not [ Condition: IsProxyPasswordSecret ] + + DoOverrideContainerInsights: !Not [ !Equals [ !FindInMap [ Cluster, Configuration, ContainerInsights ], "" ] ] + + EnableAutoScaling: !Not [ !Equals [ !Ref TargetMetric, "Disabled"] ] + +Outputs: + OrchestratorHost: + Description: Host to which fargate workload agents need to connect + Value: !GetAtt SysdigLoadBalancer.DNSName + OrchestratorPort: + Description: The port the fargate workload agent needs to connect to + Value: !Ref SysdigOrchestratorAgentPort + +Resources: + SysdigAgentCluster: + Type: AWS::ECS::Cluster + Properties: + ClusterSettings: + - !If + - DoOverrideContainerInsights + - Name: containerInsights + Value: !FindInMap [ Cluster, Configuration, ContainerInsights ] + - !Ref AWS::NoValue + Tags: + - Key: application + Value: sysdig + + SysdigOrchestratorAgentLogs: + Type: AWS::Logs::LogGroup + Properties: + RetentionInDays: 365 + + SysdigOrchestratorAgentExecutionRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: 'sts:AssumeRole' + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy' + Policies: + - !If + - DoFetchSecretAccessKey + - PolicyName: "SysdigGetSecretAccessKey" + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - "secretsmanager:GetSecretValue" + Resource: !Sub + - "arn:aws:secretsmanager:${Region}:${AwsAccountId}:secret:${SecretName}" + - Region: !Select [3, !Split [ ":", !Ref SysdigAccessKey]] + AwsAccountId: !Select [4, !Split [ ":", !Ref SysdigAccessKey]] + SecretName: !Select [6, !Split [ ":", !Ref SysdigAccessKey]] + - !Ref AWS::NoValue + - !If + - DoFetchSecretProxyPassword + - PolicyName: "SysdigGetSecretHttpProxyPassword" + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - "secretsmanager:GetSecretValue" + Resource: !Sub + - "arn:aws:secretsmanager:${Region}:${AwsAccountId}:secret:${SecretName}" + - Region: !Select [ 3, !Split [ ":", !FindInMap [ Configuration, HttpProxy, ProxyPassword ] ] ] + AwsAccountId: !Select [ 4, !Split [ ":", !FindInMap [ Configuration, HttpProxy, ProxyPassword ] ] ] + SecretName: !Select [ 6, !Split [ ":", !FindInMap [ Configuration, HttpProxy, ProxyPassword ] ] ] + - !Ref AWS::NoValue + Tags: + - Key: application + Value: sysdig + + SysdigOrchestratorAgentSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Allow workload-agent to connect + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: !Ref SysdigOrchestratorAgentPort + ToPort: !Ref SysdigOrchestratorAgentPort + CidrIp: 0.0.0.0/0 + Tags: + - Key: application + Value: sysdig + + SysdigOrchestratorAgent: + Type: AWS::ECS::TaskDefinition + DependsOn: SysdigOrchestratorAgentLogs + Properties: + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Cpu: 2048 + Memory: 8GB + ExecutionRoleArn: !Ref SysdigOrchestratorAgentExecutionRole + ContainerDefinitions: + - Name: OrchestratorAgent + Image: !Ref SysdigOrchestratorAgentImage + Secrets: + - !If + - DoFetchSecretAccessKey + - Name: ACCESS_KEY + ValueFrom: !Ref SysdigAccessKey + - !Ref AWS::NoValue + - !If + - DoFetchSecretProxyPassword + - Name: PROXY_PASSWORD + ValueFrom: !FindInMap [ Configuration, HttpProxy, ProxyPassword ] + - !Ref AWS::NoValue + Environment: + - !If + - DoFetchSecretAccessKey + - !Ref AWS::NoValue + - Name: ACCESS_KEY + Value: !Ref SysdigAccessKey + - Name: COLLECTOR + Value: !Ref SysdigCollectorHost + - Name: COLLECTOR_PORT + Value: !Ref SysdigCollectorPort + - Name: TAGS + Value: !Ref SysdigAgentTags + - Name: CHECK_CERTIFICATE + Value: !Ref SysdigCheckCollectorCertificate + - Name: SYSDIG_ORCHESTRATOR_PORT + Value: !Ref SysdigOrchestratorAgentPort + # Upload custom collector CA certificate + - !If + - DoUploadCollectorCACertificate + - Name: COLLECTOR_CA_CERTIFICATE_TYPE + Value: !FindInMap [ CACertificate, Collector, Type ] + - !Ref AWS::NoValue + - !If + - DoUploadCollectorCACertificate + - Name: COLLECTOR_CA_CERTIFICATE_VALUE + Value: !FindInMap [ CACertificate, Collector, Value ] + - !Ref AWS::NoValue + - !If + - DoUploadCollectorCACertificate + - Name: COLLECTOR_CA_CERTIFICATE_PATH + Value: !FindInMap [ CACertificate, Collector, Path ] + - !Ref AWS::NoValue + # Configure custom collector CA certificate + - !If + - DoConfigureCollectorCACertificate + - Name: COLLECTOR_CA_CERTIFICATE + Value: !FindInMap [ Configuration, Collector, CACertificate ] + - !Ref AWS::NoValue + # Upload HTTP Proxy CA certificate + - !If + - DoUploadHttpProxyCACertificate + - Name: HTTP_PROXY_CA_CERTIFICATE_TYPE + Value: !FindInMap [ CACertificate, HttpProxy, Type ] + - !Ref AWS::NoValue + - !If + - DoUploadHttpProxyCACertificate + - Name: HTTP_PROXY_CA_CERTIFICATE_VALUE + Value: !FindInMap [ CACertificate, HttpProxy, Value ] + - !Ref AWS::NoValue + - !If + - DoUploadHttpProxyCACertificate + - Name: HTTP_PROXY_CA_CERTIFICATE_PATH + Value: !FindInMap [ CACertificate, HttpProxy, Path ] + - !Ref AWS::NoValue + # Configure HTTP Proxy + - !If + - DoConfigureHttpProxy + - Name: PROXY_HOST + Value: !FindInMap [ Configuration, HttpProxy, ProxyHost ] + - !Ref AWS::NoValue + - !If + - DoConfigureHttpProxy + - Name: PROXY_PORT + Value: !FindInMap [ Configuration, HttpProxy, ProxyPort ] + - !Ref AWS::NoValue + - !If + - DoConfigureHttpProxy + - Name: PROXY_USER + Value: !FindInMap [ Configuration, HttpProxy, ProxyUser ] + - !Ref AWS::NoValue + - !If + - DoUseCleartextProxyPassword + - Name: PROXY_PASSWORD + Value: !FindInMap [ Configuration, HttpProxy, ProxyPassword ] + - !Ref AWS::NoValue + - !If + - DoConfigureHttpProxy + - Name: PROXY_SSL + Value: !FindInMap [ Configuration, HttpProxy, SSL ] + - !Ref AWS::NoValue + - !If + - DoConfigureHttpProxy + - Name: PROXY_SSL_VERIFY_CERTIFICATE + Value: !FindInMap [ Configuration, HttpProxy, SSLVerifyCertificate ] + - !Ref AWS::NoValue + - !If + - DoConfigureHttpProxy + - Name: PROXY_CA_CERTIFICATE + Value: !FindInMap [ Configuration, HttpProxy, CACertificate ] + - !Ref AWS::NoValue + PortMappings: + - ContainerPort: !Ref SysdigOrchestratorAgentPort + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: !Ref AWS::Region + awslogs-group: !Ref SysdigOrchestratorAgentLogs + awslogs-stream-prefix: ecs + Tags: + - Key: application + Value: sysdig + + SysdigLoadBalancer: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + IpAddressType: ipv4 + Scheme: internal + Type: network + Subnets: + - !Ref SubnetA + - !Ref SubnetB + Tags: + - Key: application + Value: sysdig + + SysdigTargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + Port: !Ref SysdigOrchestratorAgentPort + Protocol: TCP + TargetType: ip + TargetGroupAttributes: + - Key: deregistration_delay.timeout_seconds + Value: 60 # default is 300 + VpcId: !Ref VPC + + SysdigLoadBalancerListener: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - TargetGroupArn: !Ref SysdigTargetGroup + Type: forward + LoadBalancerArn: !Ref SysdigLoadBalancer + Port: !Ref SysdigOrchestratorAgentPort + Protocol: TCP + + SysdigOrchestratorAgentService: + Type: AWS::ECS::Service + DependsOn: + - SysdigLoadBalancerListener + Properties: + ServiceName: SysdigOrchestratorAgent + Cluster: !Ref SysdigAgentCluster + TaskDefinition: !Ref SysdigOrchestratorAgent + DeploymentConfiguration: + MinimumHealthyPercent: 100 + MaximumPercent: 200 + DesiredCount: 1 + LaunchType: FARGATE + PlatformVersion: 1.4.0 + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: !If [IsPublicSubnet, "ENABLED", "DISABLED"] + Subnets: + - !Ref SubnetA + - !Ref SubnetB + SecurityGroups: + - !Ref SysdigOrchestratorAgentSecurityGroup + LoadBalancers: + - ContainerName: OrchestratorAgent + ContainerPort: !Ref SysdigOrchestratorAgentPort + TargetGroupArn: !Ref SysdigTargetGroup + Tags: + - Key: application + Value: sysdig + + AutoScalingRole: + Condition: EnableAutoScaling + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: ecs-tasks.amazonaws.com + Action: 'sts:AssumeRole' + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole' + + ECSScalableTarget: + Condition: EnableAutoScaling + Type: AWS::ApplicationAutoScaling::ScalableTarget + Properties: + MaxCapacity: !Ref MaxCapacity + MinCapacity: "1" + RoleARN: !GetAtt AutoScalingRole.Arn + ServiceNamespace: ecs + ScalableDimension: 'ecs:service:DesiredCount' + ResourceId: !Join + - / + - - service + - !Ref SysdigAgentCluster + - !GetAtt SysdigOrchestratorAgentService.Name + + ServiceScalingPolicyCPU: + Condition: EnableAutoScaling + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Sub "${AWS::StackName}-autoscaling" + PolicyType: TargetTrackingScaling + ScalingTargetId: !Ref ECSScalableTarget + TargetTrackingScalingPolicyConfiguration: + TargetValue: !Ref TargetValue + ScaleInCooldown: !Ref ScaleInCooldown + ScaleOutCooldown: !Ref ScaleOutCooldown + PredefinedMetricSpecification: + PredefinedMetricType: !Ref TargetMetric