Cada um dos seus comandos é executado em um PowerShell separado, portanto, setx AWS_ACCESS_KEY_ID
define a variável em uma instância do shell e sai. Então setx AWS_SECRET_ACCESS_KEY
define outra variável em um novo shell e sai. Então você executa aws s3 sync
em ainda outro shell onde nenhuma das variáveis anteriores existem e falha porque as variáveis de credenciais não existem no shell .
Em vez de chamá-lo de metadados, você pode fazer algo como:
"UserData": {
"Fn::Base64": { "Fn::Join": ["", [
"<script>\n",
"cfn-init.exe -v -s [...]\n",
"setx AWS_ACCESS_KEY_ID ", { "Ref": "AutomationUserAK" }, "\n",
"setx AWS_SECRET_ACCESS_KEY ", { "Ref": "AutomationUserSK" }, "\n",
"aws s3 sync s3://some-s3-bucket d:/dev/\n",
"</script>"
] ] }
}
Nesse caso, todos serão executados na mesma instância do shell e as chaves ainda serão definidas quando você chamar aws s3 sync
.
Use os Papéis do IAM
No entanto, devo dizer que passar o acesso e chaves secretas para o modelo CloudFormation é uma prática ruim . Em vez disso, o modelo do CloudFormation deve criar IAM Role com as permissões apropriadas para acessar o bucket do S3 e atribuí-lo à instância do EC2. A ferramenta aws
na instância terá acesso transparente ao S3 sem a necessidade de fornecer chaves de acesso e secretas. Algo como isso deve ser feito com seu modelo do CloudFormation:
Primeiro, crie a Função do IAM com a política de acesso do S3 (ajuste a política para as suas necessidades):
"InstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": [ "ec2.amazonaws.com" ] },
"Action": [ "sts:AssumeRole" ]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "S3_Access",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [ "s3:List*", "s3:Get*" ],
"Resource": "*"
}
]
}
}
]
}
},
Em seguida, crie um perfil de instância do IAM que se refira à função IAM acima ...
"InstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref": "InstanceRole" }
]
}
},
E, finalmente, crie a Instância do EC2 que obtém esse Perfil do IAM atribuído (e por sua vez, Função do IAM com a política de acesso do S3).
"Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"IamInstanceProfile": { "Ref": "InstanceProfile" },
[...],
"UserData": {
"Fn::Base64": { "Fn::Join": ["", [
"<script>\n",
"cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" }, " -r Instance --region ", { "Ref" : "AWS::Region" }, "\n",
"</script>"
] ] }
}
},
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"commands" : {
"Pullcode" : {
"command" : "aws s3 sync s3://some-s3-bucket d:/dev/ --debug"
}
}
}
}
}
},
Ao usar IAM Roles , as credenciais da AWS são geradas dinamicamente e transparentemente obtidas pelo comando aws
. Isso é muito mais seguro e uma maneira preferível de fornecer às instâncias do EC2 acesso aos recursos da AWS.
Saiba mais sobre as Funções de Instância do EC2, por exemplo, aqui: link
Espero que ajude:)