web-dev-qa-db-fra.com

Importer des données postgres dans RDS à l'aide de S3 et AWS_S3

J'ai du mal à importer des données de S3 dans une instance RDS Postgres. selon les docs , vous pouvez utiliser cette syntaxe:

aws_s3.table_import_from_s3 (
   table_name text, 
   column_list text, 
   options text, 
   bucket text, 
   file_path text, 
   region text, 
   access_key text, 
   secret_key text, 
   session_token text 
) 

Donc, à Pgadmin, j'ai fait ceci:

SELECT aws_s3.table_import_from_s3(
  'contacts_1', 
  'firstname,lastname,imported', 
  '(format csv)',
  'com.foo.mybucket', 
  'mydir/subdir/myfile.csv', 
  'us-east-2',
  'AKIAYYXUMxxxxxxxxxxx',
  '3zB4S5jb1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
);

Je l'ai également essayé avec une null explicite pour le dernier paramètre.

Le message d'erreur que je reçois est:

NOTICE:  CURL error code: 51 when attempting to validate pre-signed URL, 1 attempt(s) remaining
NOTICE:  CURL error code: 51 when attempting to validate pre-signed URL, 0 attempt(s) remaining

ERROR:  Unable to generate pre-signed url, look at engine log for details.
SQL state: XX000

J'ai vérifié les journaux du serveur et il n'y avait plus d'informations supplémentaires.

J'ai triple-vérifié l'exactitude de tous les paramètres. Comment faire ce travail?

Mise à jour:

Je peux confirmer que je peux faire un S3.getObject () dans le Java AWS SDK en utilisant ces mêmes informations d'identification.

9
ccleve

Le problème principal ici est que vous devez ajouter 1) ajouter un rôle IAM à l'instance RDS pour accéder au godet S3 et 2) Ajoutez un point de terminaison S3 au VPC où l'instance RDS est exécutée afin de permettre aux communications.

C'est la procédure que j'ai suivie pour le faire fonctionner, en utilisant des commandes AWS CLI dans une coquille (prenez soin de la valeur correctement les variables environnementales impliquées), espérons pouvoir aider:

  1. Créer le rôle IAM:
$ aws iam create-role \
    --role-name $ROLE_NAME \
    --assume-role-policy-document '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Principal": {"Service": "rds.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'
  1. Créez la stratégie IAM qui sera jointe au rôle IAM:
$ aws iam create-policy \
    --policy-name $POLICY_NAME \
    --policy-document '{"Version": "2012-10-17", "Statement": [{"Sid": "s3import", "Action": ["s3:GetObject", "s3:ListBucket"], "Effect": "Allow", "Resource": ["arn:aws:s3:::${BUCKET_NAME}", "arn:aws:s3:::${BUCKET_NAME}/*"]}]}'
  1. Joindre la politique:
$ aws iam attach-role-policy \
    --policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/$POLICY_NAME \
    --role-name $ROLE_NAME
  1. Ajoutez le rôle à une instance spécifique - cette étape doit être répétée pour chaque nouvelle instance:
$ aws rds add-role-to-db-instance \
    --db-instance-identifier $RDS_INSTANCE_NAME \
    --feature-name s3Import \
    --role-arn arn:aws:iam::$AWS_ACCOUNT_ID:role/$ROLE_NAME \
    --region $REGION
  1. Créez le point d'extrémité VPC pour le service S3:
$ aws ec2 create-vpc-endpoint \
    --vpc-id $VPC_ID \
    --service-name com.amazonaws.$REGION.s3
    --route-table-ids $ROUTE_TABLE_ID

L'ID de la table d'itinéraire liée au VPC où le noeud final est créé peut être récupéré via la commande

$ aws ec2 describe-route-tables | jq -r '.RouteTables[] | "\(.VpcId) \(.RouteTableId)"'
3
Giuseppe Broccolo

Pour reproduire votre situation, j'ai fait ce qui suit:

  • Lancé une instance Amazon RDS PostgreSQL dans un sous-réseau public
  • Sous gérer les rôles iam , j'ai attribué AmazonRDSServiceRolePolicy pour s3import
  • Créé une table
  • Mettez un fichier CSV dans S3
  • Utilisé la commande SELECT aws_s3.table_import_from_s3() (comme ci-dessus) pour charger les données

Cela a fonctionné bien pour moi.

Étant donné que votre message d'erreur concerne une URL pré-signée, il suggère que les informations d'identification que vous avez fournies n'aient pas autorisé à accéder au fichier CSV dans S3. Cependant, vous dites ensuite que vous avez utilisé ces informations d'identification avec succès pour récupérer l'objet. Donc, il est peu probable que ce soit la cause.

Basé sur Reddit: avoir un problème avec AWS RDS Postgres 11+ Imports à partir de S3 à l'aide de RDS S3import Feature: AWS , la question peut être liée au fait que l'Amazon RDS L'instance est incapable d'accéder à Amazon S3 . Cela pourrait être parce qu'il est dans un sous-réseau privé sans NAT passerelle dans le VPC. Si c'est le cas , alors vous pouvez ajouter un NAT passerelle pour fournir une connectivité Internet ou, comme mentionné dans le lien, ajoutez un point d'extrémité VPC pour S3 .

Un autre commentaire dans ce poste a signalé le même problème avec une règle sortante manquante dans le groupe de sécurité , qui a arrêté l'instance RDS d'accéder à Amazon S3.

1
John Rotenstein

Vérifiez que vos RDS et S3 sont dans la même région. J'ai eu le même problème et l'a corrigé à l'aide d'un seau dans la même région mon Aurora RDS.

0
morci7

J'ai eu le même problème.

ERROR:  Unable to generate pre-signed url, look at engine log for details

cette question était liée à l'erreur:

:LOG: S3 bucket names with a period (.) are not supported

La cause fondamentale de la question, dans mon cas, était . (point) dans le nom de la godet.

0

J'ai résolu le même problème lorsqu'il est déployé des grappes de production sous des sous-réseaux privés.

Veuillez vérifier votre cluster Security Group's Outbound (mon cas)

Et ajouter également RDS-importer-jouer pour "gérer les rôles iam" avec la fonction SELECT est S3Import

J'espère que ça vous aide.

0
user3019996