
Semelhante ao que é descrito neste artigo [0], a empresa para a qual trabalho usa uma conta Bastion AWS para armazenar usuários IAM e outras contas AWS para separar diferentes ambientes de execução (prod, dev, etc.). A razão pela qual isso é importante é que temos várias contas da AWS e, em alguns casos exclusivos, essas contas da AWS precisam de acesso a um único bucket S3.
Uma maneira de permitir que isso funcione corretamente é definir uma política de bucket que permita acesso ao bucket do endpoint S3 a partir de uma VPC de uma conta AWS específica.
Política de bucket para
data-warehouse
{ "Sid": "access-from-dev-VPCE", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::data-warehouse", "arn:aws:s3:::data-warehouse/*" ], "Condition": { "StringEquals": { "aws:sourceVpce": "vpce-d95b05b0" } } }
Política de função para função
EMRRole
{ "Sid": "AllowRoleToListBucket", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::data-warehouse", ] }, { "Sid": "AllowRoleToGetBucketObjects", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::data-warehouse/*" }
Infelizmente, isso não funciona até que eu defina explicitamente a ACL paracada objetopara permitir controle total desse objeto pelo proprietário da conta AWS da qual estou acessando. Se eu não fizer isso, recebo:
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
Minha instância em que estou executando (EMR) tem a função correta:
[hadoop@ip-10-137-221-91 tmp]$ aws sts get-caller-identity
{
"Account": "1234567890",
"UserId": "AROAIGVIL6ZDI6SR87KXO:i-0eaf8a5ca52876835",
"Arn": "arn:aws:sts::1234567890:assumed-role/EMRRole/i-0eaf8a5ca52876835"
}
A ACL de um objeto no data-warehouse
bucket é semelhante a esta:
aws s3api get-object-acl --bucket=data-warehouse --key=content_category/build=2017-11-23/part0000.gz.parquet
{
"Owner": {
"DisplayName": "aws+dev",
"ID": "YXJzdGFyc3RhcnRzadc6frYXJzdGFyc3RhcnN0"
},
"Grants": [
{
"Grantee": {
"Type": "CanonicalUser",
"DisplayName": "aws+dev",
"ID": "YXJzdGFyc3RhcnRzadc6frYXJzdGFyc3RhcnN0"
},
"Permission": "FULL_CONTROL"
}
]
}
Na ACL acima, a dev
conta AWS será capaz de ler o objeto, mas outra conta AWS, digamos prod
,nãoser capaz de ler o objeto até que ele seja adicionado como "Beneficiário".
Minha pergunta:Existe uma maneira de ler/gravar objetos em um bucket S3 de várias contas da AWS sem precisar definir ACLs em cada objeto individual?
Nota: usamos spark para escrever em s3 usando s3a.
Responder1
Embora eu não tenha encontrado uma maneira de definir ACLs por objeto, há uma maneira de garantir que as ACLs sejam definidas corretamente no upload usando uma política de bucket. Este exemplo de política mostra como permitir que uma conta da AWS faça upload de objetos para seu bucket e exige que o proprietário do bucket receba controle total de todos os objetos carregados:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSourceAccount0123456789ToPutObjects",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0123456789:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::data-warehouse/*"
},
{
"Sid": "RequireAllUploadedObjectsToAssignFullControlToBucketOwner",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::data-warehouse/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
A chave é a negação explícita que verifica o x-amz-acl: bucket-owner-full-control
cabeçalho (mencionado por Michael-sqlbot nos comentários) e falha em qualquer upload onde não estiver definido. Ao usar a AWS CLI para fazer upload de arquivos, isso requer o--acl proprietário-do-balde-controle totalsinalizador a ser definido.
Exemplo:
aws s3 cp example-file.txt s3://data-warehouse/example-file.txt --profile aws-profile-name --acl bucket-owner-full-control
Esperamos que a AWS forneça uma maneira de lidar com ACLs de maneira mais elegante em algum momento.