AWSTemplateFormatVersion: "2010-09-09" Description: A nested stack of Cisco Secure Firewall Cloud Native that installs Secure Firewall Helm chart into an existing cluster (qs-1s3afab72). Metadata: cfn-lint: { config: { ignore_checks: [ W9002, W9003, W9004, W9006 ] } } Parameters: ClusterID: AllowedPattern: ".+" Type: String Version: Type: String AllowedPattern: ".+" Description: Helm chart version. SystemNamespace: Type: String AllowedPattern: ".+" Default: sfcn-system DataplaneNamespace: Type: String Default: "" Controlplane: Type: String AllowedValues: [ Enabled, Disabled ] Default: Enabled Description: Install Secure Firewall controlplane as part of Helm release. Dataplane: Type: String AllowedValues: [ Enabled, Disabled ] Default: Enabled Description: Install Secure Firewall dataplane as part of Helm release. SmartLicenseToken: Type: String NoEcho: true MaxLicenseCount: Type: Number StorageType: Type: String AllowedValues: [ local, efs ] Default: local Description: The type of a storage used to keep logs and deployments files. EnforcerConfigurationTier: Description: Instance tier to be used by enforcer workers. Default: "vCPU4-c5.2xlarge" Type: String AllowedValues: [ "vCPU4-m5.xlarge", "vCPU4-c5.2xlarge" ] ConstraintDescription: must specify vCPU4-m5.xlarge or vCPU4-c5.2xlarge EnforcerCachePort: Type: Number Default: 6379 MinValue: 1 MaxValue: 65535 Description: Port number to use for communicating with Redis server. EnforcerServiceRoles: Type: String Default: default AllowedPattern: "[a-zA-Z0-9-]{3,15}(,[a-zA-Z0-9-]{3,15})*" AllowedValues: [ "default", "default,vpnredirector" ] ConstraintDescription: | Role should be alphanumeric and can contain the special character, hyphen (-). Role must be at least 3 characters and upto 15 characters long. Description: | The service role of the data plane node. Leave the setting as "default" if you selected 1 data plane node. Each additional service role requires a corresponding data plane node. EnforcerCacheAuthToken: Type: String NoEcho: true MaxLength: 128 AllowedPattern: "([a-zA-Z0-9!&#$^><-]{16,128})?" Default: "" ConstraintDescription: Must be blank or contain at least 16 and up to 128 alphanumeric or allowed special characters. Description: | Blank or 16-128 alphanumeric characters. Only permitted special characters are !, &, #, $, ^, <, >, and -. Takes effect only if in-transit encryption is enabled. EnforcerCacheStorageKey: Type: String NoEcho: true MaxLength: 64 Default: "" AllowedPattern: "^([A-F0-9]{64})?$" ConstraintDescription: Must be a string of length 64 consisting of uppercase hexadecimal characters (A-F,0-9). Description: | User-provided AES-256 key that is 64 hexadecimal characters (A-F,0-9) used to encrypt sensitive cache data before it leaves CNFW. This can be generated with the command "openssl enc -aes-256-cbc -k password -P -md sha256" or any other AES key generation methods. Required when 'elasticache' cache type is specified. EnforcerAutoscaling: Type: String AllowedValues: [ Enabled, Disabled ] Default: Disabled Description: Enable the default Enforcer autoscaling. EnforcerCacheHost: Type: String Default: "" Name: Type: String Description: Helm chart release name. Conditions: EnforcerAutoscalingEnabled: !Equals [ !Ref EnforcerAutoscaling, Enabled ] DataplaneEnabled: !Equals [ !Ref Dataplane, Enabled ] ControlplaneEnabled: !Equals [ !Ref Controlplane, Enabled ] DataplaneNamespaceProvided: !Not [ !Equals [ !Ref DataplaneNamespace, "" ] ] DefaultRolePresent: !Or - !Equals [ !Ref EnforcerServiceRoles, "default" ] - !Equals [ !Ref EnforcerServiceRoles, "default,vpnredirector" ] VpnRedirectorRolePresent: !Equals [ !Ref EnforcerServiceRoles, "default,vpnredirector" ] LicenseTokenProvided: !Not [ !Equals [ !Ref SmartLicenseToken, "" ] ] LicenseTokenProvided&DefaultRolePresent: !And - !Condition LicenseTokenProvided - !Condition DefaultRolePresent LicenseTokenProvided&VpnRedirectorRolePresent: !And - !Condition LicenseTokenProvided - !Condition VpnRedirectorRolePresent Mappings: DataplaneTierMap: "vCPU4-m5.xlarge": dataplaneTier: "vCPU4" "vCPU4-c5.2xlarge": dataplaneTier: "vCPU4" Resources: ChartName: Type: Custom::CliQuery Properties: # Here and in other cases the Version is added to re-read values from SSM upon the Version change Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallChartName --query '{Value: Parameters[0].Value || `sfcn-bundle`}' IdField: 'Value' ChartRepo: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallChartRepo --query '{Value: Parameters[0].Value || `https://d2rxbueeojmoz9.cloudfront.net`}' IdField: 'Value' ChartRepoUsername: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallChartRepoUsername --query '{Value: Parameters[0].Value || ``}' IdField: 'Value' ChartRepoPassword: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallChartRepoPassword --query '{Value: Parameters[0].Value || ``}' --with-decryption IdField: 'Value' ContainerRegistry: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallContainerRegistry --query '{Value: Parameters[0].Value || `709825985650.dkr.ecr.us-east-1.amazonaws.com`}' IdField: 'Value' ContainerRegistryUsername: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallContainerRegistryUsername --query '{Value: Parameters[0].Value || ``}' IdField: 'Value' ContainerRegistryPassword: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallContainerRegistryPassword --query '{Value: Parameters[0].Value || ``}' --with-decryption IdField: 'Value' ContainerRepo: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/firewallContainerRepo --query '{Value: Parameters[0].Value || `cisco/sfcn/prod`}' IdField: 'Value' LicensingEnabled: Type: Custom::CliQuery Properties: Version: !Ref Version ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader' AwsCliCommand: !Sub | ssm get-parameters --names /CSFCN/${ClusterID}/licensingEnabled --query '{Value: Parameters[0].Value || `"true"`}' IdField: 'Value' SecureFirewall: Type: "AWSQS::Kubernetes::Helm" Properties: ClusterID: !Ref ClusterID Name: !Ref Name Namespace: !Ref SystemNamespace Chart: !GetAtt ChartName.Value Version: !Ref Version Repository: !GetAtt ChartRepo.Value RepositoryOptions: Username: !GetAtt ChartRepoUsername.Value Password: !GetAtt ChartRepoPassword.Value Values: "global.acceptEULA": "yes" "global.platform": "eks" "global.storageType": !Ref StorageType "global.imageCredentials.registry": !GetAtt ContainerRegistry.Value "global.imageCredentials.artifactoryRepo": !GetAtt ContainerRepo.Value "global.imageCredentials.username": !GetAtt ContainerRegistryUsername.Value "global.imageCredentials.password": !GetAtt ContainerRegistryPassword.Value "global.dataPlaneNamespace": !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ] "tags.controlPlane": !If [ ControlplaneEnabled, "true", "false" ] "tags.dataPlane": !If [ DataplaneEnabled, "true", "false" ] "snmpExporter.serviceRoles": !Sub "{${EnforcerServiceRoles}}" "dataPlane.serviceRoles": !Sub "{${EnforcerServiceRoles}}" "dataPlane.redis.host": !Ref EnforcerCacheHost "dataPlane.redis.port": !Ref EnforcerCachePort "dataPlane.redis.storage_key": !Ref EnforcerCacheStorageKey "dataPlane.redis.token": !Ref EnforcerCacheAuthToken "dataPlane.hpa.enable": !If [ EnforcerAutoscalingEnabled, "true", "false" ] "dataPlane.configurationTier": !FindInMap [ DataplaneTierMap, !Ref EnforcerConfigurationTier, dataplaneTier ] "dataPlane.enableLicensing": !GetAtt LicensingEnabled.Value "scaledown.enable": !If [ EnforcerAutoscalingEnabled, "true", "false" ] CSSMSecret: DependsOn: SecureFirewall Condition: LicenseTokenProvided Type: AWSQS::Kubernetes::Resource Properties: ClusterName: !Ref ClusterID Namespace: !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ] Manifest: !Sub - |- apiVersion: v1 kind: Secret metadata: name: cssm-token data: token: ${token} - token: Fn::Base64: !Ref SmartLicenseToken SmartLicenseDefault: DependsOn: CSSMSecret Type: AWSQS::Kubernetes::Resource Condition: LicenseTokenProvided&DefaultRolePresent Properties: ClusterName: !Ref ClusterID Namespace: !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ] Manifest: !Sub - |- apiVersion: sfcn.cisco.com/v1 kind: SmartLicense metadata: name: sfcn-enforcer spec: action: "REGISTER" tokenSecret: name: cssm-token namespace: ${tokenNamespace} minLicenseCount: 1 maxLicenseCount: ${MaxLicenseCount} scalingRef: kind: ${scalingRefKind} name: sfcn-enforcer - tokenNamespace: !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ] scalingRefKind: !If [ EnforcerAutoscalingEnabled, "HorizontalPodAutoscaler", "Deployment" ] SmartLicenseVpnRedirector: DependsOn: CSSMSecret Type: AWSQS::Kubernetes::Resource Condition: LicenseTokenProvided&VpnRedirectorRolePresent Properties: ClusterName: !Ref ClusterID Namespace: !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ] Manifest: !Sub - |- apiVersion: sfcn.cisco.com/v1 kind: SmartLicense metadata: name: sfcn-vpnredirector-enforcer spec: action: "REGISTER" tokenSecret: name: cssm-token namespace: ${tokenNamespace} minLicenseCount: 1 maxLicenseCount: 4 scalingRef: kind: Deployment name: sfcn-vpnredirector-enforcer - tokenNamespace: !If [ DataplaneNamespaceProvided, !Ref DataplaneNamespace, !Ref SystemNamespace ]