turbot/aws_compliance

Query: vpc_subnet_public_and_private

Usage

powerpipe query aws_compliance.query.vpc_subnet_public_and_private

SQL

with subnets_with_explicit_route as (
select
distinct (a ->> 'SubnetId') as all_sub
from
aws_vpc_route_table as t,
jsonb_array_elements(associations) as a
where
a ->> 'SubnetId' is not null
),
public_subnets_with_explicit_route as (
select
distinct a ->> 'SubnetId' as SubnetId
from
aws_vpc_route_table as t,
jsonb_array_elements(associations) as a,
jsonb_array_elements(routes) as r
where
r ->> 'DestinationCidrBlock' = '0.0.0.0/0'
and (
r ->> 'GatewayId' like 'igw-%'
or r ->> 'NatGatewayId' like 'nat-%'
)
and a ->> 'SubnetId' is not null
),
public_subnets_with_implicit_route as (
select
distinct route_table_id,
vpc_id,
region
from
aws_vpc_route_table as t,
jsonb_array_elements(associations) as a,
jsonb_array_elements(routes) as r
where
a ->> 'Main' = 'true'
and r ->> 'DestinationCidrBlock' = '0.0.0.0/0'
and (
r ->> 'GatewayId' like 'igw-%'
or r ->> 'NatGatewayId' like 'nat-%'
)
),
subnet_accessibility as (
select
subnet_id,
vpc_id,
case
when s.subnet_id in (
select
all_sub
from
subnets_with_explicit_route
where
all_sub not in (
select
SubnetId
from
public_subnets_with_explicit_route
)
) then 'private'
when p.SubnetId is not null
or s.vpc_id in (
select
vpc_id
from
public_subnets_with_implicit_route
) then 'public'
else 'private'
end as access
from
aws_vpc_subnet as s
left join public_subnets_with_explicit_route as p on p.SubnetId = s.subnet_id
)
select
arn as resource,
case
when v.vpc_id not in (
select
vpc_id
from
subnet_accessibility
) then 'alarm'
when 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then 'ok'
when 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and not 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then 'alarm'
when 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and not 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then 'alarm'
end as status,
case
when v.vpc_id not in (
select
vpc_id
from
subnet_accessibility
) then v.title || ' has no subnet.'
when 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then v.title || ' having both private and public subnet(s).'
when 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and not 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then v.title || ' having only public subnet(s).'
when 'private' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
)
and not 'public' in (
select
access
from
subnet_accessibility
where
vpc_id = v.vpc_id
) then v.title || ' having only private subnet(s).'
end as reason,
region,
account_id
from
aws_vpc as v;

Controls

The query is being used by the following controls: