# coding=utf-8
# *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. ***
# *** Do not edit by hand unless you're certain you know what you are doing! ***

import copy
import warnings
import pulumi
import pulumi.runtime
from typing import Any, Mapping, Optional, Sequence, Union, overload
from .. import _utilities
from . import outputs
from ._inputs import *

__all__ = ['ServicePerimeterArgs', 'ServicePerimeter']

@pulumi.input_type
class ServicePerimeterArgs:
    def __init__(__self__, *,
                 parent: pulumi.Input[str],
                 title: pulumi.Input[str],
                 description: Optional[pulumi.Input[str]] = None,
                 name: Optional[pulumi.Input[str]] = None,
                 perimeter_type: Optional[pulumi.Input[str]] = None,
                 spec: Optional[pulumi.Input['ServicePerimeterSpecArgs']] = None,
                 status: Optional[pulumi.Input['ServicePerimeterStatusArgs']] = None,
                 use_explicit_dry_run_spec: Optional[pulumi.Input[bool]] = None):
        """
        The set of arguments for constructing a ServicePerimeter resource.
        :param pulumi.Input[str] parent: The AccessPolicy this ServicePerimeter lives in.
               Format: accessPolicies/{policy_id}
        :param pulumi.Input[str] title: Human readable title. Must be unique within the Policy.
        :param pulumi.Input[str] description: Description of the ServicePerimeter and its use. Does not affect
               behavior.
        :param pulumi.Input[str] name: Resource name for the ServicePerimeter. The short_name component must
               begin with a letter and only include alphanumeric and '_'.
               Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        :param pulumi.Input[str] perimeter_type: Specifies the type of the Perimeter. There are two types: regular and
               bridge. Regular Service Perimeter contains resources, access levels,
               and restricted services. Every resource can be in at most
               ONE regular Service Perimeter.
               In addition to being in a regular service perimeter, a resource can also
               be in zero or more perimeter bridges. A perimeter bridge only contains
               resources. Cross project operations are permitted if all effected
               resources share some perimeter (whether bridge or regular). Perimeter
               Bridge does not contain access levels or services: those are governed
               entirely by the regular perimeter that resource is in.
               Perimeter Bridges are typically useful when building more complex
               topologies with many independent perimeters that need to share some data
               with a common perimeter, but should not be able to share data among
               themselves.
               Default value is `PERIMETER_TYPE_REGULAR`.
               Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        :param pulumi.Input['ServicePerimeterSpecArgs'] spec: Proposed (or dry run) ServicePerimeter configuration.
               This configuration allows to specify and test ServicePerimeter configuration
               without enforcing actual access restrictions. Only allowed to be set when
               the `useExplicitDryRunSpec` flag is set.
               Structure is documented below.
        :param pulumi.Input['ServicePerimeterStatusArgs'] status: ServicePerimeter configuration. Specifies sets of resources,
               restricted services and access levels that determine
               perimeter content and boundaries.
               Structure is documented below.
        :param pulumi.Input[bool] use_explicit_dry_run_spec: Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
               for all Service Perimeters, and that spec is identical to the status for those
               Service Perimeters. When this flag is set, it inhibits the generation of the
               implicit spec, thereby allowing the user to explicitly provide a
               configuration ("spec") to use in a dry-run version of the Service Perimeter.
               This allows the user to test changes to the enforced config ("status") without
               actually enforcing them. This testing is done through analyzing the differences
               between currently enforced and suggested restrictions. useExplicitDryRunSpec must
               bet set to True if any of the fields in the spec are set to non-default values.
        """
        pulumi.set(__self__, "parent", parent)
        pulumi.set(__self__, "title", title)
        if description is not None:
            pulumi.set(__self__, "description", description)
        if name is not None:
            pulumi.set(__self__, "name", name)
        if perimeter_type is not None:
            pulumi.set(__self__, "perimeter_type", perimeter_type)
        if spec is not None:
            pulumi.set(__self__, "spec", spec)
        if status is not None:
            pulumi.set(__self__, "status", status)
        if use_explicit_dry_run_spec is not None:
            pulumi.set(__self__, "use_explicit_dry_run_spec", use_explicit_dry_run_spec)

    @property
    @pulumi.getter
    def parent(self) -> pulumi.Input[str]:
        """
        The AccessPolicy this ServicePerimeter lives in.
        Format: accessPolicies/{policy_id}
        """
        return pulumi.get(self, "parent")

    @parent.setter
    def parent(self, value: pulumi.Input[str]):
        pulumi.set(self, "parent", value)

    @property
    @pulumi.getter
    def title(self) -> pulumi.Input[str]:
        """
        Human readable title. Must be unique within the Policy.
        """
        return pulumi.get(self, "title")

    @title.setter
    def title(self, value: pulumi.Input[str]):
        pulumi.set(self, "title", value)

    @property
    @pulumi.getter
    def description(self) -> Optional[pulumi.Input[str]]:
        """
        Description of the ServicePerimeter and its use. Does not affect
        behavior.
        """
        return pulumi.get(self, "description")

    @description.setter
    def description(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "description", value)

    @property
    @pulumi.getter
    def name(self) -> Optional[pulumi.Input[str]]:
        """
        Resource name for the ServicePerimeter. The short_name component must
        begin with a letter and only include alphanumeric and '_'.
        Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        """
        return pulumi.get(self, "name")

    @name.setter
    def name(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "name", value)

    @property
    @pulumi.getter(name="perimeterType")
    def perimeter_type(self) -> Optional[pulumi.Input[str]]:
        """
        Specifies the type of the Perimeter. There are two types: regular and
        bridge. Regular Service Perimeter contains resources, access levels,
        and restricted services. Every resource can be in at most
        ONE regular Service Perimeter.
        In addition to being in a regular service perimeter, a resource can also
        be in zero or more perimeter bridges. A perimeter bridge only contains
        resources. Cross project operations are permitted if all effected
        resources share some perimeter (whether bridge or regular). Perimeter
        Bridge does not contain access levels or services: those are governed
        entirely by the regular perimeter that resource is in.
        Perimeter Bridges are typically useful when building more complex
        topologies with many independent perimeters that need to share some data
        with a common perimeter, but should not be able to share data among
        themselves.
        Default value is `PERIMETER_TYPE_REGULAR`.
        Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        """
        return pulumi.get(self, "perimeter_type")

    @perimeter_type.setter
    def perimeter_type(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "perimeter_type", value)

    @property
    @pulumi.getter
    def spec(self) -> Optional[pulumi.Input['ServicePerimeterSpecArgs']]:
        """
        Proposed (or dry run) ServicePerimeter configuration.
        This configuration allows to specify and test ServicePerimeter configuration
        without enforcing actual access restrictions. Only allowed to be set when
        the `useExplicitDryRunSpec` flag is set.
        Structure is documented below.
        """
        return pulumi.get(self, "spec")

    @spec.setter
    def spec(self, value: Optional[pulumi.Input['ServicePerimeterSpecArgs']]):
        pulumi.set(self, "spec", value)

    @property
    @pulumi.getter
    def status(self) -> Optional[pulumi.Input['ServicePerimeterStatusArgs']]:
        """
        ServicePerimeter configuration. Specifies sets of resources,
        restricted services and access levels that determine
        perimeter content and boundaries.
        Structure is documented below.
        """
        return pulumi.get(self, "status")

    @status.setter
    def status(self, value: Optional[pulumi.Input['ServicePerimeterStatusArgs']]):
        pulumi.set(self, "status", value)

    @property
    @pulumi.getter(name="useExplicitDryRunSpec")
    def use_explicit_dry_run_spec(self) -> Optional[pulumi.Input[bool]]:
        """
        Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
        for all Service Perimeters, and that spec is identical to the status for those
        Service Perimeters. When this flag is set, it inhibits the generation of the
        implicit spec, thereby allowing the user to explicitly provide a
        configuration ("spec") to use in a dry-run version of the Service Perimeter.
        This allows the user to test changes to the enforced config ("status") without
        actually enforcing them. This testing is done through analyzing the differences
        between currently enforced and suggested restrictions. useExplicitDryRunSpec must
        bet set to True if any of the fields in the spec are set to non-default values.
        """
        return pulumi.get(self, "use_explicit_dry_run_spec")

    @use_explicit_dry_run_spec.setter
    def use_explicit_dry_run_spec(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "use_explicit_dry_run_spec", value)


@pulumi.input_type
class _ServicePerimeterState:
    def __init__(__self__, *,
                 create_time: Optional[pulumi.Input[str]] = None,
                 description: Optional[pulumi.Input[str]] = None,
                 name: Optional[pulumi.Input[str]] = None,
                 parent: Optional[pulumi.Input[str]] = None,
                 perimeter_type: Optional[pulumi.Input[str]] = None,
                 spec: Optional[pulumi.Input['ServicePerimeterSpecArgs']] = None,
                 status: Optional[pulumi.Input['ServicePerimeterStatusArgs']] = None,
                 title: Optional[pulumi.Input[str]] = None,
                 update_time: Optional[pulumi.Input[str]] = None,
                 use_explicit_dry_run_spec: Optional[pulumi.Input[bool]] = None):
        """
        Input properties used for looking up and filtering ServicePerimeter resources.
        :param pulumi.Input[str] create_time: Time the AccessPolicy was created in UTC.
        :param pulumi.Input[str] description: Description of the ServicePerimeter and its use. Does not affect
               behavior.
        :param pulumi.Input[str] name: Resource name for the ServicePerimeter. The short_name component must
               begin with a letter and only include alphanumeric and '_'.
               Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        :param pulumi.Input[str] parent: The AccessPolicy this ServicePerimeter lives in.
               Format: accessPolicies/{policy_id}
        :param pulumi.Input[str] perimeter_type: Specifies the type of the Perimeter. There are two types: regular and
               bridge. Regular Service Perimeter contains resources, access levels,
               and restricted services. Every resource can be in at most
               ONE regular Service Perimeter.
               In addition to being in a regular service perimeter, a resource can also
               be in zero or more perimeter bridges. A perimeter bridge only contains
               resources. Cross project operations are permitted if all effected
               resources share some perimeter (whether bridge or regular). Perimeter
               Bridge does not contain access levels or services: those are governed
               entirely by the regular perimeter that resource is in.
               Perimeter Bridges are typically useful when building more complex
               topologies with many independent perimeters that need to share some data
               with a common perimeter, but should not be able to share data among
               themselves.
               Default value is `PERIMETER_TYPE_REGULAR`.
               Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        :param pulumi.Input['ServicePerimeterSpecArgs'] spec: Proposed (or dry run) ServicePerimeter configuration.
               This configuration allows to specify and test ServicePerimeter configuration
               without enforcing actual access restrictions. Only allowed to be set when
               the `useExplicitDryRunSpec` flag is set.
               Structure is documented below.
        :param pulumi.Input['ServicePerimeterStatusArgs'] status: ServicePerimeter configuration. Specifies sets of resources,
               restricted services and access levels that determine
               perimeter content and boundaries.
               Structure is documented below.
        :param pulumi.Input[str] title: Human readable title. Must be unique within the Policy.
        :param pulumi.Input[str] update_time: Time the AccessPolicy was updated in UTC.
        :param pulumi.Input[bool] use_explicit_dry_run_spec: Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
               for all Service Perimeters, and that spec is identical to the status for those
               Service Perimeters. When this flag is set, it inhibits the generation of the
               implicit spec, thereby allowing the user to explicitly provide a
               configuration ("spec") to use in a dry-run version of the Service Perimeter.
               This allows the user to test changes to the enforced config ("status") without
               actually enforcing them. This testing is done through analyzing the differences
               between currently enforced and suggested restrictions. useExplicitDryRunSpec must
               bet set to True if any of the fields in the spec are set to non-default values.
        """
        if create_time is not None:
            pulumi.set(__self__, "create_time", create_time)
        if description is not None:
            pulumi.set(__self__, "description", description)
        if name is not None:
            pulumi.set(__self__, "name", name)
        if parent is not None:
            pulumi.set(__self__, "parent", parent)
        if perimeter_type is not None:
            pulumi.set(__self__, "perimeter_type", perimeter_type)
        if spec is not None:
            pulumi.set(__self__, "spec", spec)
        if status is not None:
            pulumi.set(__self__, "status", status)
        if title is not None:
            pulumi.set(__self__, "title", title)
        if update_time is not None:
            pulumi.set(__self__, "update_time", update_time)
        if use_explicit_dry_run_spec is not None:
            pulumi.set(__self__, "use_explicit_dry_run_spec", use_explicit_dry_run_spec)

    @property
    @pulumi.getter(name="createTime")
    def create_time(self) -> Optional[pulumi.Input[str]]:
        """
        Time the AccessPolicy was created in UTC.
        """
        return pulumi.get(self, "create_time")

    @create_time.setter
    def create_time(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "create_time", value)

    @property
    @pulumi.getter
    def description(self) -> Optional[pulumi.Input[str]]:
        """
        Description of the ServicePerimeter and its use. Does not affect
        behavior.
        """
        return pulumi.get(self, "description")

    @description.setter
    def description(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "description", value)

    @property
    @pulumi.getter
    def name(self) -> Optional[pulumi.Input[str]]:
        """
        Resource name for the ServicePerimeter. The short_name component must
        begin with a letter and only include alphanumeric and '_'.
        Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        """
        return pulumi.get(self, "name")

    @name.setter
    def name(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "name", value)

    @property
    @pulumi.getter
    def parent(self) -> Optional[pulumi.Input[str]]:
        """
        The AccessPolicy this ServicePerimeter lives in.
        Format: accessPolicies/{policy_id}
        """
        return pulumi.get(self, "parent")

    @parent.setter
    def parent(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "parent", value)

    @property
    @pulumi.getter(name="perimeterType")
    def perimeter_type(self) -> Optional[pulumi.Input[str]]:
        """
        Specifies the type of the Perimeter. There are two types: regular and
        bridge. Regular Service Perimeter contains resources, access levels,
        and restricted services. Every resource can be in at most
        ONE regular Service Perimeter.
        In addition to being in a regular service perimeter, a resource can also
        be in zero or more perimeter bridges. A perimeter bridge only contains
        resources. Cross project operations are permitted if all effected
        resources share some perimeter (whether bridge or regular). Perimeter
        Bridge does not contain access levels or services: those are governed
        entirely by the regular perimeter that resource is in.
        Perimeter Bridges are typically useful when building more complex
        topologies with many independent perimeters that need to share some data
        with a common perimeter, but should not be able to share data among
        themselves.
        Default value is `PERIMETER_TYPE_REGULAR`.
        Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        """
        return pulumi.get(self, "perimeter_type")

    @perimeter_type.setter
    def perimeter_type(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "perimeter_type", value)

    @property
    @pulumi.getter
    def spec(self) -> Optional[pulumi.Input['ServicePerimeterSpecArgs']]:
        """
        Proposed (or dry run) ServicePerimeter configuration.
        This configuration allows to specify and test ServicePerimeter configuration
        without enforcing actual access restrictions. Only allowed to be set when
        the `useExplicitDryRunSpec` flag is set.
        Structure is documented below.
        """
        return pulumi.get(self, "spec")

    @spec.setter
    def spec(self, value: Optional[pulumi.Input['ServicePerimeterSpecArgs']]):
        pulumi.set(self, "spec", value)

    @property
    @pulumi.getter
    def status(self) -> Optional[pulumi.Input['ServicePerimeterStatusArgs']]:
        """
        ServicePerimeter configuration. Specifies sets of resources,
        restricted services and access levels that determine
        perimeter content and boundaries.
        Structure is documented below.
        """
        return pulumi.get(self, "status")

    @status.setter
    def status(self, value: Optional[pulumi.Input['ServicePerimeterStatusArgs']]):
        pulumi.set(self, "status", value)

    @property
    @pulumi.getter
    def title(self) -> Optional[pulumi.Input[str]]:
        """
        Human readable title. Must be unique within the Policy.
        """
        return pulumi.get(self, "title")

    @title.setter
    def title(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "title", value)

    @property
    @pulumi.getter(name="updateTime")
    def update_time(self) -> Optional[pulumi.Input[str]]:
        """
        Time the AccessPolicy was updated in UTC.
        """
        return pulumi.get(self, "update_time")

    @update_time.setter
    def update_time(self, value: Optional[pulumi.Input[str]]):
        pulumi.set(self, "update_time", value)

    @property
    @pulumi.getter(name="useExplicitDryRunSpec")
    def use_explicit_dry_run_spec(self) -> Optional[pulumi.Input[bool]]:
        """
        Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
        for all Service Perimeters, and that spec is identical to the status for those
        Service Perimeters. When this flag is set, it inhibits the generation of the
        implicit spec, thereby allowing the user to explicitly provide a
        configuration ("spec") to use in a dry-run version of the Service Perimeter.
        This allows the user to test changes to the enforced config ("status") without
        actually enforcing them. This testing is done through analyzing the differences
        between currently enforced and suggested restrictions. useExplicitDryRunSpec must
        bet set to True if any of the fields in the spec are set to non-default values.
        """
        return pulumi.get(self, "use_explicit_dry_run_spec")

    @use_explicit_dry_run_spec.setter
    def use_explicit_dry_run_spec(self, value: Optional[pulumi.Input[bool]]):
        pulumi.set(self, "use_explicit_dry_run_spec", value)


class ServicePerimeter(pulumi.CustomResource):
    @overload
    def __init__(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 description: Optional[pulumi.Input[str]] = None,
                 name: Optional[pulumi.Input[str]] = None,
                 parent: Optional[pulumi.Input[str]] = None,
                 perimeter_type: Optional[pulumi.Input[str]] = None,
                 spec: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterSpecArgs']]] = None,
                 status: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterStatusArgs']]] = None,
                 title: Optional[pulumi.Input[str]] = None,
                 use_explicit_dry_run_spec: Optional[pulumi.Input[bool]] = None,
                 __props__=None):
        """
        ServicePerimeter describes a set of GCP resources which can freely import
        and export data amongst themselves, but not export outside of the
        ServicePerimeter. If a request with a source within this ServicePerimeter
        has a target outside of the ServicePerimeter, the request will be blocked.
        Otherwise the request is allowed. There are two types of Service Perimeter
        - Regular and Bridge. Regular Service Perimeters cannot overlap, a single
          GCP project can only belong to a single regular Service Perimeter. Service
          Perimeter Bridges can contain only GCP projects as members, a single GCP
          project may belong to multiple Service Perimeter Bridges.

        To get more information about ServicePerimeter, see:

        * [API documentation](https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters)
        * How-to Guides
            * [Service Perimeter Quickstart](https://cloud.google.com/vpc-service-controls/docs/quickstart)

        > **Warning:** If you are using User ADCs (Application Default Credentials) with this resource,
        you must specify a `billing_project` and set `user_project_override` to true
        in the provider configuration. Otherwise the ACM API will return a 403 error.
        Your account must have the `serviceusage.services.use` permission on the
        `billing_project` you defined.

        ## Example Usage
        ### Access Context Manager Service Perimeter Basic

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        service_perimeter = gcp.accesscontextmanager.ServicePerimeter("service-perimeter",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=["storage.googleapis.com"],
            ),
            title="restrict_storage")
        access_level = gcp.accesscontextmanager.AccessLevel("access-level",
            basic=gcp.accesscontextmanager.AccessLevelBasicArgs(
                conditions=[gcp.accesscontextmanager.AccessLevelBasicConditionArgs(
                    device_policy=gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyArgs(
                        os_constraints=[gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyOsConstraintArgs(
                            os_type="DESKTOP_CHROME_OS",
                        )],
                        require_screen_lock=False,
                    ),
                    regions=[
                        "CH",
                        "IT",
                        "US",
                    ],
                )],
            ),
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            title="chromeos_no_lock")
        ```
        ### Access Context Manager Service Perimeter Secure Data Exchange

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        secure_data_exchange = gcp.accesscontextmanager.ServicePerimeters("secure-data-exchange",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            service_perimeters=[
                gcp.accesscontextmanager.ServicePerimetersServicePerimeterArgs(
                    name=access_policy.name.apply(lambda name: f"accessPolicies/{name}/servicePerimeters/"),
                    title="",
                    status=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusArgs(
                        restricted_services=["storage.googleapis.com"],
                    ),
                ),
                gcp.accesscontextmanager.ServicePerimetersServicePerimeterArgs(
                    name=access_policy.name.apply(lambda name: f"accessPolicies/{name}/servicePerimeters/"),
                    title="",
                    status=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusArgs(
                        restricted_services=["bigtable.googleapis.com"],
                        vpc_accessible_services=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusVpcAccessibleServicesArgs(
                            enable_restriction=True,
                            allowed_services=["bigquery.googleapis.com"],
                        ),
                    ),
                ),
            ])
        access_level = gcp.accesscontextmanager.AccessLevel("access-level",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            title="secure_data_exchange",
            basic=gcp.accesscontextmanager.AccessLevelBasicArgs(
                conditions=[gcp.accesscontextmanager.AccessLevelBasicConditionArgs(
                    device_policy=gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyArgs(
                        require_screen_lock=False,
                        os_constraints=[gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyOsConstraintArgs(
                            os_type="DESKTOP_CHROME_OS",
                        )],
                    ),
                    regions=[
                        "CH",
                        "IT",
                        "US",
                    ],
                )],
            ))
        test_access = gcp.accesscontextmanager.ServicePerimeter("test-access",
            parent=f"accessPolicies/{google_access_context_manager_access_policy['test-access']['name']}",
            title="%s",
            perimeter_type="PERIMETER_TYPE_REGULAR",
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=[
                    "bigquery.googleapis.com",
                    "storage.googleapis.com",
                ],
                access_levels=[access_level.name],
                vpc_accessible_services=gcp.accesscontextmanager.ServicePerimeterStatusVpcAccessibleServicesArgs(
                    enable_restriction=True,
                    allowed_services=[
                        "bigquery.googleapis.com",
                        "storage.googleapis.com",
                    ],
                ),
                ingress_policies=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyArgs(
                    ingress_from=gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressFromArgs(
                        sources=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressFromSourceArgs(
                            access_level=google_access_context_manager_access_level["test-access"]["name"],
                        )],
                        identity_type="ANY_IDENTITY",
                    ),
                    ingress_to=gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToArgs(
                        resources=["*"],
                        operations=[
                            gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationArgs(
                                service_name="bigquery.googleapis.com",
                                method_selectors=[
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        method="BigQueryStorage.ReadRows",
                                    ),
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        method="TableService.ListTables",
                                    ),
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        permission="bigquery.jobs.get",
                                    ),
                                ],
                            ),
                            gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationArgs(
                                service_name="storage.googleapis.com",
                                method_selectors=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                    method="google.storage.objects.create",
                                )],
                            ),
                        ],
                    ),
                )],
                egress_policies=[gcp.accesscontextmanager.ServicePerimeterStatusEgressPolicyArgs(
                    egress_from=gcp.accesscontextmanager.ServicePerimeterStatusEgressPolicyEgressFromArgs(
                        identity_type="ANY_USER_ACCOUNT",
                    ),
                )],
            ))
        ```
        ### Access Context Manager Service Perimeter Dry Run

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        service_perimeter = gcp.accesscontextmanager.ServicePerimeter("service-perimeter",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            spec=gcp.accesscontextmanager.ServicePerimeterSpecArgs(
                restricted_services=["storage.googleapis.com"],
            ),
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=["bigquery.googleapis.com"],
            ),
            title="restrict_bigquery_dryrun_storage",
            use_explicit_dry_run_spec=True)
        ```

        ## Import

        ServicePerimeter can be imported using any of these accepted formats

        ```sh
         $ pulumi import gcp:accesscontextmanager/servicePerimeter:ServicePerimeter default {{name}}
        ```

        :param str resource_name: The name of the resource.
        :param pulumi.ResourceOptions opts: Options for the resource.
        :param pulumi.Input[str] description: Description of the ServicePerimeter and its use. Does not affect
               behavior.
        :param pulumi.Input[str] name: Resource name for the ServicePerimeter. The short_name component must
               begin with a letter and only include alphanumeric and '_'.
               Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        :param pulumi.Input[str] parent: The AccessPolicy this ServicePerimeter lives in.
               Format: accessPolicies/{policy_id}
        :param pulumi.Input[str] perimeter_type: Specifies the type of the Perimeter. There are two types: regular and
               bridge. Regular Service Perimeter contains resources, access levels,
               and restricted services. Every resource can be in at most
               ONE regular Service Perimeter.
               In addition to being in a regular service perimeter, a resource can also
               be in zero or more perimeter bridges. A perimeter bridge only contains
               resources. Cross project operations are permitted if all effected
               resources share some perimeter (whether bridge or regular). Perimeter
               Bridge does not contain access levels or services: those are governed
               entirely by the regular perimeter that resource is in.
               Perimeter Bridges are typically useful when building more complex
               topologies with many independent perimeters that need to share some data
               with a common perimeter, but should not be able to share data among
               themselves.
               Default value is `PERIMETER_TYPE_REGULAR`.
               Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        :param pulumi.Input[pulumi.InputType['ServicePerimeterSpecArgs']] spec: Proposed (or dry run) ServicePerimeter configuration.
               This configuration allows to specify and test ServicePerimeter configuration
               without enforcing actual access restrictions. Only allowed to be set when
               the `useExplicitDryRunSpec` flag is set.
               Structure is documented below.
        :param pulumi.Input[pulumi.InputType['ServicePerimeterStatusArgs']] status: ServicePerimeter configuration. Specifies sets of resources,
               restricted services and access levels that determine
               perimeter content and boundaries.
               Structure is documented below.
        :param pulumi.Input[str] title: Human readable title. Must be unique within the Policy.
        :param pulumi.Input[bool] use_explicit_dry_run_spec: Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
               for all Service Perimeters, and that spec is identical to the status for those
               Service Perimeters. When this flag is set, it inhibits the generation of the
               implicit spec, thereby allowing the user to explicitly provide a
               configuration ("spec") to use in a dry-run version of the Service Perimeter.
               This allows the user to test changes to the enforced config ("status") without
               actually enforcing them. This testing is done through analyzing the differences
               between currently enforced and suggested restrictions. useExplicitDryRunSpec must
               bet set to True if any of the fields in the spec are set to non-default values.
        """
        ...
    @overload
    def __init__(__self__,
                 resource_name: str,
                 args: ServicePerimeterArgs,
                 opts: Optional[pulumi.ResourceOptions] = None):
        """
        ServicePerimeter describes a set of GCP resources which can freely import
        and export data amongst themselves, but not export outside of the
        ServicePerimeter. If a request with a source within this ServicePerimeter
        has a target outside of the ServicePerimeter, the request will be blocked.
        Otherwise the request is allowed. There are two types of Service Perimeter
        - Regular and Bridge. Regular Service Perimeters cannot overlap, a single
          GCP project can only belong to a single regular Service Perimeter. Service
          Perimeter Bridges can contain only GCP projects as members, a single GCP
          project may belong to multiple Service Perimeter Bridges.

        To get more information about ServicePerimeter, see:

        * [API documentation](https://cloud.google.com/access-context-manager/docs/reference/rest/v1/accessPolicies.servicePerimeters)
        * How-to Guides
            * [Service Perimeter Quickstart](https://cloud.google.com/vpc-service-controls/docs/quickstart)

        > **Warning:** If you are using User ADCs (Application Default Credentials) with this resource,
        you must specify a `billing_project` and set `user_project_override` to true
        in the provider configuration. Otherwise the ACM API will return a 403 error.
        Your account must have the `serviceusage.services.use` permission on the
        `billing_project` you defined.

        ## Example Usage
        ### Access Context Manager Service Perimeter Basic

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        service_perimeter = gcp.accesscontextmanager.ServicePerimeter("service-perimeter",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=["storage.googleapis.com"],
            ),
            title="restrict_storage")
        access_level = gcp.accesscontextmanager.AccessLevel("access-level",
            basic=gcp.accesscontextmanager.AccessLevelBasicArgs(
                conditions=[gcp.accesscontextmanager.AccessLevelBasicConditionArgs(
                    device_policy=gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyArgs(
                        os_constraints=[gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyOsConstraintArgs(
                            os_type="DESKTOP_CHROME_OS",
                        )],
                        require_screen_lock=False,
                    ),
                    regions=[
                        "CH",
                        "IT",
                        "US",
                    ],
                )],
            ),
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            title="chromeos_no_lock")
        ```
        ### Access Context Manager Service Perimeter Secure Data Exchange

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        secure_data_exchange = gcp.accesscontextmanager.ServicePerimeters("secure-data-exchange",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            service_perimeters=[
                gcp.accesscontextmanager.ServicePerimetersServicePerimeterArgs(
                    name=access_policy.name.apply(lambda name: f"accessPolicies/{name}/servicePerimeters/"),
                    title="",
                    status=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusArgs(
                        restricted_services=["storage.googleapis.com"],
                    ),
                ),
                gcp.accesscontextmanager.ServicePerimetersServicePerimeterArgs(
                    name=access_policy.name.apply(lambda name: f"accessPolicies/{name}/servicePerimeters/"),
                    title="",
                    status=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusArgs(
                        restricted_services=["bigtable.googleapis.com"],
                        vpc_accessible_services=gcp.accesscontextmanager.ServicePerimetersServicePerimeterStatusVpcAccessibleServicesArgs(
                            enable_restriction=True,
                            allowed_services=["bigquery.googleapis.com"],
                        ),
                    ),
                ),
            ])
        access_level = gcp.accesscontextmanager.AccessLevel("access-level",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            title="secure_data_exchange",
            basic=gcp.accesscontextmanager.AccessLevelBasicArgs(
                conditions=[gcp.accesscontextmanager.AccessLevelBasicConditionArgs(
                    device_policy=gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyArgs(
                        require_screen_lock=False,
                        os_constraints=[gcp.accesscontextmanager.AccessLevelBasicConditionDevicePolicyOsConstraintArgs(
                            os_type="DESKTOP_CHROME_OS",
                        )],
                    ),
                    regions=[
                        "CH",
                        "IT",
                        "US",
                    ],
                )],
            ))
        test_access = gcp.accesscontextmanager.ServicePerimeter("test-access",
            parent=f"accessPolicies/{google_access_context_manager_access_policy['test-access']['name']}",
            title="%s",
            perimeter_type="PERIMETER_TYPE_REGULAR",
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=[
                    "bigquery.googleapis.com",
                    "storage.googleapis.com",
                ],
                access_levels=[access_level.name],
                vpc_accessible_services=gcp.accesscontextmanager.ServicePerimeterStatusVpcAccessibleServicesArgs(
                    enable_restriction=True,
                    allowed_services=[
                        "bigquery.googleapis.com",
                        "storage.googleapis.com",
                    ],
                ),
                ingress_policies=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyArgs(
                    ingress_from=gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressFromArgs(
                        sources=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressFromSourceArgs(
                            access_level=google_access_context_manager_access_level["test-access"]["name"],
                        )],
                        identity_type="ANY_IDENTITY",
                    ),
                    ingress_to=gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToArgs(
                        resources=["*"],
                        operations=[
                            gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationArgs(
                                service_name="bigquery.googleapis.com",
                                method_selectors=[
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        method="BigQueryStorage.ReadRows",
                                    ),
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        method="TableService.ListTables",
                                    ),
                                    gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                        permission="bigquery.jobs.get",
                                    ),
                                ],
                            ),
                            gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationArgs(
                                service_name="storage.googleapis.com",
                                method_selectors=[gcp.accesscontextmanager.ServicePerimeterStatusIngressPolicyIngressToOperationMethodSelectorArgs(
                                    method="google.storage.objects.create",
                                )],
                            ),
                        ],
                    ),
                )],
                egress_policies=[gcp.accesscontextmanager.ServicePerimeterStatusEgressPolicyArgs(
                    egress_from=gcp.accesscontextmanager.ServicePerimeterStatusEgressPolicyEgressFromArgs(
                        identity_type="ANY_USER_ACCOUNT",
                    ),
                )],
            ))
        ```
        ### Access Context Manager Service Perimeter Dry Run

        ```python
        import pulumi
        import pulumi_gcp as gcp

        access_policy = gcp.accesscontextmanager.AccessPolicy("access-policy",
            parent="organizations/123456789",
            title="my policy")
        service_perimeter = gcp.accesscontextmanager.ServicePerimeter("service-perimeter",
            parent=access_policy.name.apply(lambda name: f"accessPolicies/{name}"),
            spec=gcp.accesscontextmanager.ServicePerimeterSpecArgs(
                restricted_services=["storage.googleapis.com"],
            ),
            status=gcp.accesscontextmanager.ServicePerimeterStatusArgs(
                restricted_services=["bigquery.googleapis.com"],
            ),
            title="restrict_bigquery_dryrun_storage",
            use_explicit_dry_run_spec=True)
        ```

        ## Import

        ServicePerimeter can be imported using any of these accepted formats

        ```sh
         $ pulumi import gcp:accesscontextmanager/servicePerimeter:ServicePerimeter default {{name}}
        ```

        :param str resource_name: The name of the resource.
        :param ServicePerimeterArgs args: The arguments to use to populate this resource's properties.
        :param pulumi.ResourceOptions opts: Options for the resource.
        """
        ...
    def __init__(__self__, resource_name: str, *args, **kwargs):
        resource_args, opts = _utilities.get_resource_args_opts(ServicePerimeterArgs, pulumi.ResourceOptions, *args, **kwargs)
        if resource_args is not None:
            __self__._internal_init(resource_name, opts, **resource_args.__dict__)
        else:
            __self__._internal_init(resource_name, *args, **kwargs)

    def _internal_init(__self__,
                 resource_name: str,
                 opts: Optional[pulumi.ResourceOptions] = None,
                 description: Optional[pulumi.Input[str]] = None,
                 name: Optional[pulumi.Input[str]] = None,
                 parent: Optional[pulumi.Input[str]] = None,
                 perimeter_type: Optional[pulumi.Input[str]] = None,
                 spec: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterSpecArgs']]] = None,
                 status: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterStatusArgs']]] = None,
                 title: Optional[pulumi.Input[str]] = None,
                 use_explicit_dry_run_spec: Optional[pulumi.Input[bool]] = None,
                 __props__=None):
        opts = pulumi.ResourceOptions.merge(_utilities.get_resource_opts_defaults(), opts)
        if not isinstance(opts, pulumi.ResourceOptions):
            raise TypeError('Expected resource options to be a ResourceOptions instance')
        if opts.id is None:
            if __props__ is not None:
                raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource')
            __props__ = ServicePerimeterArgs.__new__(ServicePerimeterArgs)

            __props__.__dict__["description"] = description
            __props__.__dict__["name"] = name
            if parent is None and not opts.urn:
                raise TypeError("Missing required property 'parent'")
            __props__.__dict__["parent"] = parent
            __props__.__dict__["perimeter_type"] = perimeter_type
            __props__.__dict__["spec"] = spec
            __props__.__dict__["status"] = status
            if title is None and not opts.urn:
                raise TypeError("Missing required property 'title'")
            __props__.__dict__["title"] = title
            __props__.__dict__["use_explicit_dry_run_spec"] = use_explicit_dry_run_spec
            __props__.__dict__["create_time"] = None
            __props__.__dict__["update_time"] = None
        super(ServicePerimeter, __self__).__init__(
            'gcp:accesscontextmanager/servicePerimeter:ServicePerimeter',
            resource_name,
            __props__,
            opts)

    @staticmethod
    def get(resource_name: str,
            id: pulumi.Input[str],
            opts: Optional[pulumi.ResourceOptions] = None,
            create_time: Optional[pulumi.Input[str]] = None,
            description: Optional[pulumi.Input[str]] = None,
            name: Optional[pulumi.Input[str]] = None,
            parent: Optional[pulumi.Input[str]] = None,
            perimeter_type: Optional[pulumi.Input[str]] = None,
            spec: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterSpecArgs']]] = None,
            status: Optional[pulumi.Input[pulumi.InputType['ServicePerimeterStatusArgs']]] = None,
            title: Optional[pulumi.Input[str]] = None,
            update_time: Optional[pulumi.Input[str]] = None,
            use_explicit_dry_run_spec: Optional[pulumi.Input[bool]] = None) -> 'ServicePerimeter':
        """
        Get an existing ServicePerimeter resource's state with the given name, id, and optional extra
        properties used to qualify the lookup.

        :param str resource_name: The unique name of the resulting resource.
        :param pulumi.Input[str] id: The unique provider ID of the resource to lookup.
        :param pulumi.ResourceOptions opts: Options for the resource.
        :param pulumi.Input[str] create_time: Time the AccessPolicy was created in UTC.
        :param pulumi.Input[str] description: Description of the ServicePerimeter and its use. Does not affect
               behavior.
        :param pulumi.Input[str] name: Resource name for the ServicePerimeter. The short_name component must
               begin with a letter and only include alphanumeric and '_'.
               Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        :param pulumi.Input[str] parent: The AccessPolicy this ServicePerimeter lives in.
               Format: accessPolicies/{policy_id}
        :param pulumi.Input[str] perimeter_type: Specifies the type of the Perimeter. There are two types: regular and
               bridge. Regular Service Perimeter contains resources, access levels,
               and restricted services. Every resource can be in at most
               ONE regular Service Perimeter.
               In addition to being in a regular service perimeter, a resource can also
               be in zero or more perimeter bridges. A perimeter bridge only contains
               resources. Cross project operations are permitted if all effected
               resources share some perimeter (whether bridge or regular). Perimeter
               Bridge does not contain access levels or services: those are governed
               entirely by the regular perimeter that resource is in.
               Perimeter Bridges are typically useful when building more complex
               topologies with many independent perimeters that need to share some data
               with a common perimeter, but should not be able to share data among
               themselves.
               Default value is `PERIMETER_TYPE_REGULAR`.
               Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        :param pulumi.Input[pulumi.InputType['ServicePerimeterSpecArgs']] spec: Proposed (or dry run) ServicePerimeter configuration.
               This configuration allows to specify and test ServicePerimeter configuration
               without enforcing actual access restrictions. Only allowed to be set when
               the `useExplicitDryRunSpec` flag is set.
               Structure is documented below.
        :param pulumi.Input[pulumi.InputType['ServicePerimeterStatusArgs']] status: ServicePerimeter configuration. Specifies sets of resources,
               restricted services and access levels that determine
               perimeter content and boundaries.
               Structure is documented below.
        :param pulumi.Input[str] title: Human readable title. Must be unique within the Policy.
        :param pulumi.Input[str] update_time: Time the AccessPolicy was updated in UTC.
        :param pulumi.Input[bool] use_explicit_dry_run_spec: Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
               for all Service Perimeters, and that spec is identical to the status for those
               Service Perimeters. When this flag is set, it inhibits the generation of the
               implicit spec, thereby allowing the user to explicitly provide a
               configuration ("spec") to use in a dry-run version of the Service Perimeter.
               This allows the user to test changes to the enforced config ("status") without
               actually enforcing them. This testing is done through analyzing the differences
               between currently enforced and suggested restrictions. useExplicitDryRunSpec must
               bet set to True if any of the fields in the spec are set to non-default values.
        """
        opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id))

        __props__ = _ServicePerimeterState.__new__(_ServicePerimeterState)

        __props__.__dict__["create_time"] = create_time
        __props__.__dict__["description"] = description
        __props__.__dict__["name"] = name
        __props__.__dict__["parent"] = parent
        __props__.__dict__["perimeter_type"] = perimeter_type
        __props__.__dict__["spec"] = spec
        __props__.__dict__["status"] = status
        __props__.__dict__["title"] = title
        __props__.__dict__["update_time"] = update_time
        __props__.__dict__["use_explicit_dry_run_spec"] = use_explicit_dry_run_spec
        return ServicePerimeter(resource_name, opts=opts, __props__=__props__)

    @property
    @pulumi.getter(name="createTime")
    def create_time(self) -> pulumi.Output[str]:
        """
        Time the AccessPolicy was created in UTC.
        """
        return pulumi.get(self, "create_time")

    @property
    @pulumi.getter
    def description(self) -> pulumi.Output[Optional[str]]:
        """
        Description of the ServicePerimeter and its use. Does not affect
        behavior.
        """
        return pulumi.get(self, "description")

    @property
    @pulumi.getter
    def name(self) -> pulumi.Output[str]:
        """
        Resource name for the ServicePerimeter. The short_name component must
        begin with a letter and only include alphanumeric and '_'.
        Format: accessPolicies/{policy_id}/servicePerimeters/{short_name}
        """
        return pulumi.get(self, "name")

    @property
    @pulumi.getter
    def parent(self) -> pulumi.Output[str]:
        """
        The AccessPolicy this ServicePerimeter lives in.
        Format: accessPolicies/{policy_id}
        """
        return pulumi.get(self, "parent")

    @property
    @pulumi.getter(name="perimeterType")
    def perimeter_type(self) -> pulumi.Output[Optional[str]]:
        """
        Specifies the type of the Perimeter. There are two types: regular and
        bridge. Regular Service Perimeter contains resources, access levels,
        and restricted services. Every resource can be in at most
        ONE regular Service Perimeter.
        In addition to being in a regular service perimeter, a resource can also
        be in zero or more perimeter bridges. A perimeter bridge only contains
        resources. Cross project operations are permitted if all effected
        resources share some perimeter (whether bridge or regular). Perimeter
        Bridge does not contain access levels or services: those are governed
        entirely by the regular perimeter that resource is in.
        Perimeter Bridges are typically useful when building more complex
        topologies with many independent perimeters that need to share some data
        with a common perimeter, but should not be able to share data among
        themselves.
        Default value is `PERIMETER_TYPE_REGULAR`.
        Possible values are `PERIMETER_TYPE_REGULAR` and `PERIMETER_TYPE_BRIDGE`.
        """
        return pulumi.get(self, "perimeter_type")

    @property
    @pulumi.getter
    def spec(self) -> pulumi.Output[Optional['outputs.ServicePerimeterSpec']]:
        """
        Proposed (or dry run) ServicePerimeter configuration.
        This configuration allows to specify and test ServicePerimeter configuration
        without enforcing actual access restrictions. Only allowed to be set when
        the `useExplicitDryRunSpec` flag is set.
        Structure is documented below.
        """
        return pulumi.get(self, "spec")

    @property
    @pulumi.getter
    def status(self) -> pulumi.Output[Optional['outputs.ServicePerimeterStatus']]:
        """
        ServicePerimeter configuration. Specifies sets of resources,
        restricted services and access levels that determine
        perimeter content and boundaries.
        Structure is documented below.
        """
        return pulumi.get(self, "status")

    @property
    @pulumi.getter
    def title(self) -> pulumi.Output[str]:
        """
        Human readable title. Must be unique within the Policy.
        """
        return pulumi.get(self, "title")

    @property
    @pulumi.getter(name="updateTime")
    def update_time(self) -> pulumi.Output[str]:
        """
        Time the AccessPolicy was updated in UTC.
        """
        return pulumi.get(self, "update_time")

    @property
    @pulumi.getter(name="useExplicitDryRunSpec")
    def use_explicit_dry_run_spec(self) -> pulumi.Output[Optional[bool]]:
        """
        Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly exists
        for all Service Perimeters, and that spec is identical to the status for those
        Service Perimeters. When this flag is set, it inhibits the generation of the
        implicit spec, thereby allowing the user to explicitly provide a
        configuration ("spec") to use in a dry-run version of the Service Perimeter.
        This allows the user to test changes to the enforced config ("status") without
        actually enforcing them. This testing is done through analyzing the differences
        between currently enforced and suggested restrictions. useExplicitDryRunSpec must
        bet set to True if any of the fields in the spec are set to non-default values.
        """
        return pulumi.get(self, "use_explicit_dry_run_spec")

