All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.io.cloudshiftdev.awscdklib.network.firewall.NetworkFirewall.kt Maven / Gradle / Ivy

There is a newer version: 10.1.0
Show newest version
package io.cloudshiftdev.awscdklib.network.firewall

import io.cloudshiftdev.awscdk.customresources.AwsCustomResource
import io.cloudshiftdev.awscdk.customresources.AwsCustomResourcePolicy
import io.cloudshiftdev.awscdk.customresources.PhysicalResourceId
import io.cloudshiftdev.awscdk.services.ec2.ISubnet
import io.cloudshiftdev.awscdk.services.ec2.SubnetSelection
import io.cloudshiftdev.awscdk.services.ec2.Vpc
import io.cloudshiftdev.awscdk.services.networkfirewall.CfnFirewall
import io.cloudshiftdev.awscdk.services.networkfirewall.CfnFirewallPolicy
import io.cloudshiftdev.constructs.Construct

public enum class StatelessStandardAction(internal val value: String) {
    FORWARD("aws:forward_to_sfe"),
    PASS("aws:pass"),
    DROP("aws:drop"),
}

public enum class StatefulStandardAction(internal val value: String) {
    ALERT("ALERT"),
    PASS("PASS"),
    DROP("DROP"),
}

public enum class StatefulStrictAction(internal val value: String) {
    DROP_STRICT("aws:drop_strict"),
    DROP_ESTABLISHED("aws:drop_established"),
    ALERT_STRICT("aws:alert_strict"),
    ALERT_ESTABLISHED("aws:alert_established"),
}

public class FirewallPolicy(
    scope: Construct,
    id: String,
    firewallPolicyName: String? = null,
    description: String? = null,
    statelessDefaultActions: List = emptyList(),
    statelessFragmentDefaultActions: List = emptyList(),
    statefulDefaultActions: List = emptyList(),
) : Construct(scope, id) {
    public val firewallPolicyId: String
    public val firewallPolicyArn: String

    init {
        val policy =
            CfnFirewallPolicy(this, "CfnFirewallPolicy") {
                firewallPolicyName(firewallPolicyName ?: id)
                description?.let(::description)
                firewallPolicy(
                    CfnFirewallPolicy.FirewallPolicyProperty {
                        statelessDefaultActions(statelessDefaultActions.map { it.value })
                        statelessFragmentDefaultActions(
                            statelessFragmentDefaultActions.map { it.value }
                        )
                        statefulDefaultActions(statefulDefaultActions.map { it.value })
                    }
                )
            }

        firewallPolicyId = policy.attrFirewallPolicyId()
        firewallPolicyArn = policy.attrFirewallPolicyArn()
    }
}

public class NetworkFirewall(
    scope: Construct,
    id: String,
    vpc: Vpc,
    subnetMappings: SubnetSelection,
    firewallName: String,
    firewallPolicy: FirewallPolicy
) : Construct(scope, id) {
    public val endpointIds: List
    public val firewallArn: String
    public val firewallId: String
    public val availabilityZoneEndpointMap: Map

    init {
        val placementSubnets = vpc.selectSubnets(subnetMappings).subnets()

        val nfw =
            CfnFirewall(vpc, "Firewall") {
                firewallName(firewallName)
                vpcId(vpc.vpcId())
                subnetMappings(placementSubnets.toSubnetMappings())
                firewallPolicyArn(firewallPolicy.firewallPolicyArn)
            }

        // WTF AWS:
        // https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-networkfirewall/issues/15

        val lookupNfwEndpoints =
            AwsCustomResource(scope, "FirewallCustomResource") {
                onCreate {
                    service("networkfirewall")
                    action("DescribeFirewall")
                    parameters(mapOf("FirewallArn" to nfw.attrFirewallArn()))
                    physicalResourceId(PhysicalResourceId.of(nfw.attrFirewallArn()))
                }
                onUpdate {
                    service("networkfirewall")
                    action("DescribeFirewall")
                    parameters(mapOf("FirewallArn" to nfw.attrFirewallArn()))
                    physicalResourceId(PhysicalResourceId.of(nfw.attrFirewallArn()))
                }
                installLatestAwsSdk(false)
                policy(AwsCustomResourcePolicy.fromSdkCalls { resources(nfw.attrFirewallArn()) })
            }

        val azs = placementSubnets.map { it.availabilityZone() }
        availabilityZoneEndpointMap =
            azs.associateWith {
                lookupNfwEndpoints.responseField(
                    "FirewallStatus.SyncStates.${it}.Attachment.EndpointId"
                )
            }

        endpointIds = nfw.attrEndpointIds()
        firewallArn = nfw.attrFirewallArn()
        firewallId = nfw.attrFirewallId()
    }

    private fun List.toSubnetMappings(): List {
        return map { CfnFirewall.SubnetMappingProperty { subnetId(it.subnetId()) } }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy