Externer Netzwerkzugang und private Konnektivität auf AWS

In diesem Thema finden Sie Details zur Konfiguration der ausgehenden privaten Konnektivität zu einem externen AWS-Dienst durch einen externen Netzwerkzugang. Die Hauptunterschiede zwischen den Konfigurationen für ausgehende öffentliche Konnektivität und ausgehende private Konnektivität bestehen darin, dass Sie bei der privaten Konnektivität die folgenden Operationen durchführen müssen:

  • Erstellen Sie einen privaten Konnektivitätsendpunkt. Für diesen Schritt ist die ACCOUNTADMIN-Rolle erforderlich.

  • Erstellen Sie die Netzwerkregel so, dass die Eigenschaft TYPE auf PRIVATE_HOST_PORT eingestellt ist.

Kosten für ausgehende private Konnektivität

Sie zahlen für jeden privaten Konnektivitätsendpunkt zusammen mit den insgesamt verarbeiteten Daten. Die Preise für diese Artikel finden Sie in der Snowflake Service Consumption Table.

Sie können die Kosten für diese Element ermitteln, indem Sie bei der Abfrage von Abrechnungsansichten in den Schemata ACCOUNT_USAGE und ORGANIZATION_USAGE nach den folgenden Diensttypen filtern:

  • OUTBOUND_PRIVATELINK_ENDPOINT

  • OUTBOUND_PRIVATELINK_DATA_PROCESSED

Sie können zum Beispiel die Ansicht USAGE_IN_CURRENCY_DAILY abfragen und nach folgenden Diensttypen filtern.

Einrichten einer privaten Konnektivität zu einem externen Amazon S3-Dienst

  1. Rufen Sie die Systemfunktion SYSTEM$PROVISION_PRIVATELINK_ENDPOINT auf, um anzugeben, dass Snowflake eine Verbindung zu einem AWS S3-Dienst herstellt, und um den Hostnamen anzugeben, der bei der Verbindung mit dem Dienst verwendet werden soll:

    USE ROLE ACCOUNTADMIN;
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.s3',
      '*.s3.us-west-2.amazonaws.com'
    );
    
    Copy

    Bemerkung

    Das Sternchen in *.s3.us-west-2.amazonaws.com gibt an, dass Sie den Endpunkt für den Zugriff auf mehrere S3-Buckets verwenden können.

  2. Führen Sie die folgende SQL-Anweisung aus, um eine Netzwerkregel zu erstellen, die es Snowflake ermöglicht, Anfragen an ein externes Ziel zu senden. Stellen Sie dabei sicher, dass die TYPE Eigenschaft auf PRIVATE_HOST_PORT gesetzt ist:

    CREATE OR REPLACE NETWORK RULE aws_s3_network_rule
      MODE = EGRESS
      TYPE = PRIVATE_HOST_PORT
      VALUE_LIST = ('external-access-iam-bucket.s3.us-west-2.amazonaws.com');
    
    Copy
  3. Führen Sie die folgende SQL-Anweisung aus, um eine Sicherheitsintegration für die externe API-Authentifizierung zu erstellen:

    CREATE OR REPLACE SECURITY INTEGRATION aws_s3_security_integration
      TYPE = API_AUTHENTICATION
      AUTH_TYPE = AWS_IAM
      ENABLED = TRUE
      AWS_ROLE_ARN = 'arn:aws:iam::736112632310:role/external-access-iam-bucket';
    
    Copy
  4. Führen Sie die folgende SQL-Anweisung aus, um die Werte STORAGE_AWS_IAM_USER_ARN und STORAGE_AWS_EXTERNAL_ID für den IAM-Benutzer zu erhalten:

    DESC SECURITY INTEGRATION aws_s3_security_integration;
    
    Copy
  5. Verwenden Sie die Werte STORAGE_AWS_IAM_USER_ARN und STORAGE_AWS_EXTERNAL_ID und führen Sie Schritt 5 in Option 1: Konfigurieren einer Snowflake-Speicherintegration für Zugriff auf Amazon S3 aus, um dem Benutzer IAM Zugriff auf den Amazon-S3-Dienst zu gewähren.

  6. Führen Sie die folgende SQL-Anweisung aus, um ein Token zu erstellen, das für die Authentifizierung beim AWS-S3-Dienst verwendet wird:

    CREATE OR REPLACE SECRET aws_s3_access_token
      TYPE = CLOUD_PROVIDER_TOKEN
      API_AUTHENTICATION = aws_s3_security_integration;
    
    Copy
  7. Führen Sie die folgende SQL-Anweisung aus, um eine Integration für externen Zugriff zu erstellen, die die Netzwerkregel und das Token verwendet, die die in den vorherigen Schritten wurden:

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION aws_s3_external_access_integration
      ALLOWED_NETWORK_RULES = (aws_s3_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS = (aws_s3_access_token)
      ENABLED = TRUE
      COMMENT = 'Testing S3 connectivity';
    
    Copy
  8. Führen Sie eine der folgenden SQL-Anweisungen aus, um eine Funktion zu erstellen, die die Integration für externen Zugriff und das zuvor erstellte Token verwenden kann:

    CREATE OR REPLACE FUNCTION aws_s3_python_function()
      RETURNS VARCHAR
      LANGUAGE PYTHON
      EXTERNAL_ACCESS_INTEGRATIONS = (aws_s3_external_access_integration)
      RUNTIME_VERSION = '3.8'
      SECRETS = ('cred' = aws_s3_access_token)
      PACKAGES = ('boto3')
      HANDLER = 'main_handler'
    AS
    $$
      import boto3
      import _snowflake
      from botocore.config import Config
    
      def main_handler():
          # Get the previously created token as an object
          cloud_provider_object = _snowflake.get_cloud_provider_token('cred')
    
          # Configure boto3 connection settings
          config = Config(
              retries=dict(total_max_attempts=9),
              connect_timeout=30,
              read_timeout=30,
              max_pool_connections=50
          )
    
          # Connect to S3 using boto3
          s3 = boto3.client(
              's3',
              region_name='us-west-2',
              aws_access_key_id=cloud_provider_object.access_key_id,
              aws_secret_access_key=cloud_provider_object.secret_access_key,
              aws_session_token=cloud_provider_object.token,
              config=config
          )
    
          # Use the s3 object upload/download resources
          # ...
    
          return 'Successfully connected to AWS S3'
    $$;
    
    Copy
  9. Führen Sie eine der folgenden SQL-Anweisungen aus, um die von Ihnen erstellte Funktion auszuführen:

    SELECT aws_s3_python_function();
    
    Copy

Einrichten einer privaten Konnektivität zu einem externen Amazon Bedrock-Dienst

  1. Rufen Sie die Systemfunktion SYSTEM$PROVISION_PRIVATELINK_ENDPOINT auf, um festzulegen, dass Snowflake eine Verbindung zu den Diensten AWS S3 und Amazon Bedrock herstellt und welche Hostnamen für die Verbindung zu den Diensten verwendet werden sollen:

    USE ROLE ACCOUNTADMIN;
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.s3',
      '*.s3.us-west-2.amazonaws.com'
    );
    
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.bedrock-runtime',
      'bedrock-runtime.us-west-2.amazonaws.com'
    );
    
    Copy
  2. Führen Sie die folgende SQL-Anweisung aus, um eine Netzwerkregel zu erstellen, die es Snowflake ermöglicht, Anfragen an ein externes Ziel zu senden. Stellen Sie dabei sicher, dass die TYPE Eigenschaft auf PRIVATE_HOST_PORT gesetzt ist:

    CREATE OR REPLACE NETWORK RULE bedrock_network_rule
      MODE = EGRESS
      TYPE = PRIVATE_HOST_PORT
      VALUE_LIST = ('bedrock-runtime.us-west-2.amazonaws.com');
    
    Copy
  3. Führen Sie die folgende SQL-Anweisung aus, um eine Sicherheitsintegration für die externe API-Authentifizierung zu erstellen:

    CREATE OR REPLACE SECURITY INTEGRATION bedrock_security_integration
      TYPE = API_AUTHENTICATION
      AUTH_TYPE = AWS_IAM
      ENABLED = TRUE
      AWS_ROLE_ARN = 'arn:aws:iam::736112632310:role/external-access-iam-bucket';
    
    Copy
  4. Führen Sie die folgende SQL-Anweisung aus, um die Werte STORAGE_AWS_IAM_USER_ARN und STORAGE_AWS_EXTERNAL_ID für den IAM-Benutzer zu erhalten:

    DESC  SECURITY INTEGRATION bedrock_security_integration;
    
    Copy
  5. Verwenden Sie die Werte STORAGE_AWS_IAM_USER_ARN und STORAGE_AWS_EXTERNAL_ID, folgen Sie Schritt 5 in Option 1: Konfigurieren einer Snowflake-Speicherintegration für Zugriff auf Amazon S3, um dem Benutzer IAM-Zugriff auf den Amazon Bedrock Service zu gewähren.

  6. Führen Sie die folgende SQL-Anweisung aus, um ein Token zu erstellen, das für die Authentifizierung mit dem AWS-Bedrock-Dienst verwendet wird:

    CREATE OR REPLACE SECRET aws_bedrock_access_token
      TYPE = CLOUD_PROVIDER_TOKEN
      API_AUTHENTICATION = bedrock_security_integration;
    
    Copy
  7. Führen Sie die folgende SQL-Anweisung aus, um eine Integration für externen Zugriff zu erstellen, die die Netzwerkregel und das Token verwendet, die die in den vorherigen Schritten wurden:

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION bedrock_external_access_integration
      ALLOWED_NETWORK_RULES = (bedrock_network_rule)
      ALLOWED_AUTHENTICATION_SECRETS=(aws_bedrock_access_token)
      ENABLED=true ;
    
    Copy
  8. Führen Sie die folgenden SQL-Anweisungen aus, um eine Funktion zu erstellen, die die Integration für externen Zugriff und das zuvor erstellte Token verwenden kann:

    CREATE OR REPLACE FUNCTION bedrock_private_connectivity_tests(
      id INT,
      instructions VARCHAR,
      user_context VARCHAR,
      model_id VARCHAR
    )
      RETURNS VARCHAR
      LANGUAGE PYTHON
      EXTERNAL_ACCESS_INTEGRATIONS = (bedrock_external_access_integration)
      RUNTIME_VERSION = '3.8'
      SECRETS = ('cred' = aws_bedrock_access_token)
      PACKAGES = ('boto3')
      HANDLER = 'bedrock_py'
    AS
    $$
      import boto3
      import json
      import _snowflake
      def bedrock_py(id, instructions, user_context, model_id):
          # Get the previously created token as an object
          cloud_provider_object = _snowflake.get_cloud_provider_token('cred')
          cloud_provider_dictionary = {
              "ACCESS_KEY_ID": cloud_provider_object.access_key_id,
              "SECRET_ACCESS_KEY": cloud_provider_object.secret_access_key,
              "TOKEN": cloud_provider_object.token
          }
          # Assign AWS credentials and choose a region
          boto3_session_args = {
              'aws_access_key_id': cloud_provider_dictionary["ACCESS_KEY_ID"],
              'aws_secret_access_key': cloud_provider_dictionary["SECRET_ACCESS_KEY"],
              'aws_session_token': cloud_provider_dictionary["TOKEN"],
              'region_name': 'us-west-2'
          }
          session = boto3.Session(**boto3_session_args)
          client = session.client('bedrock-runtime')
          # Prepare the request body for the specified model
          def prepare_request_body(model_id, instructions, user_context):
              default_max_tokens = 512
              default_temperature = 0.7
              default_top_p = 1.0
              if model_id == 'amazon.titan-text-express-v1':
                  body = {
                      "inputText": f"<SYSTEM>Follow these:{instructions}<END_SYSTEM>\n<USER_CONTEXT>Use this user context in your response:{user_context}<END_USER_CONTEXT>",
                      "textGenerationConfig": {
                          "maxTokenCount": default_max_tokens,
                          "stopSequences": [],
                          "temperature": default_temperature,
                          "topP": default_top_p
                      }
                  }
              elif model_id == 'ai21.j2-ultra-v1':
                  body = {
                      "prompt": f"<SYSTEM>Follow these:{instructions}<END_SYSTEM>\n<USER_CONTEXT>Use this user context in your response:{user_context}<END_USER_CONTEXT>",
                      "temperature": default_temperature,
                      "topP": default_top_p,
                      "maxTokens": default_max_tokens
                  }
              elif model_id == 'anthropic.claude-3-sonnet-20240229-v1:0':
                  body = {
                      "max_tokens": default_max_tokens,
                      "messages": [{"role": "user", "content": f"<SYSTEM>Follow these:{instructions}<END_SYSTEM>\n<USER_CONTEXT>Use this user context in your response:{user_context}<END_USER_CONTEXT>"}],
                      "anthropic_version": "bedrock-2023-05-31"
                  }
              else:
                  raise ValueError("Unsupported model ID")
              return json.dumps(body)
          # Call Bedrock to get a completion
          body = prepare_request_body(model_id, instructions, user_context)
          response = client.invoke_model(modelId=model_id, body=body)
          response_body = json.loads(response.get('body').read())
          # Parse the API response based on the model
          def get_completion_from_response(response_body, model_id):
              if model_id == 'amazon.titan-text-express-v1':
                  output_text = response_body.get('results')[0].get('outputText')
              elif model_id == 'ai21.j2-ultra-v1':
                  output_text = response_body.get('completions')[0].get('data').get('text')
              elif model_id == 'anthropic.claude-3-sonnet-20240229-v1:0':
                  output_text = response_body.get('content')[0].get('text')
              else:
                  raise ValueError("Unsupported model ID")
              return output_text
          # Get the generated text from Bedrock
          output_text = get_completion_from_response(response_body, model_id)
          return output_text
      $$;
    
    Copy
  9. Führen Sie die folgende SQL-Anweisung aus, um die von Ihnen erstellte Funktion auszuführen:

    SELECT bedrock_private_connectivity_tests();
    
    Copy