AWS Notes
5.61K subscribers
498 photos
43 videos
10 files
2.88K links
AWS Notes — Amazon Web Services Educational and Information Channel

Chat: https://t.iss.one/aws_notes_chat

Contacts: @apple_rom, https://www.linkedin.com/in/roman-siewko/
Download Telegram
При ошибках в работе с #S3 бакетами есть некоторый набор вещей, что требуется проверить, чтобы найти причину и всё исправить. Очевидные проблемы доступа (не настроенные права) не в счёт, как и вопросы шифрования (это отдельная тема). Далее выстраданные болью и болью вещи.

===
Некоторые достаточно очевидные, что нужно перебрать и проверить.
===

регион бакета - он может отличаться от того, из которого идёт доступ

• в современных регионах - только Signature Version 4

• популярные ошибки в #IAM: не стоит политика на бакет без * (звёздочки, wildcard):

"Action": [
"s3:GetObject",
"s3:ListBucket",
],
"Resource": [
"arn:aws:s3:::my-bucket",
]

... или наоборот (только с *)

"Action": [
"s3:GetObject",
"s3:ListBucket",
],
"Resource": [
"arn:aws:s3:::my-bucket/*",
]

• есть операция с каталогом, а нет политики 's3:ListBucket'

===
Некоторые не самые и совсем неочевидные (из серии #magic).
===

• сильно отличается время на инстансе (в любую сторону - несколько минут и больше), что часто даёт #error:

A client error (403) occurred when calling the HeadObject operation: Forbidden

• версия #aws_cli старая (локально на старых виртуалках)

• стоит флажок --recursive, а работа идёт с файлом (может возникнуть после копипаста в скриптах) — в результате ничего не будет - ни ошибки (что самое противное), ни копирования файла

• при операциях с https - нужно учитывать заголовки в CORS (что есть HEAD среди них, который часто по дефолту не стоит)

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="https://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

• проверяем доступ на конкретный файл с помощью

aws s3api get-object-acl --bucket my-bucket --key my-path/some.file

... если получаем ошибку:

An error occurred (AccessDenied) when calling the GetObjectAcl operation: Access Denied

... хотя точно есть все права/роли для бакета (на другой аккаунт, нужные операции и путь), то значит файлы в бакете имеют хозяина, недоступного запрашиваемому — см. выше про #shared_bucket
В нормальной ситуации был бы ответ типа:

{
"Owner": {
"DisplayName": "my-dev",
"ID": "c0123f42b8a1bed065b8a1b2fdbf76c1b6acda99e0778822e3cece21a8c71058"
},
"Grants": [
{
"Grantee": {
"Type": "CanonicalUser",
"DisplayName": "my-dev",
"ID": "c0123f42b8a1bed065b8a1b2fdbf76c1b6acda99e0778822e3cece21a8c71058"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"Type": "CanonicalUser",
"DisplayName": "jenkins",
"ID": "8933ecf5e61d2b67a525edee13f7667ab45d2be85b1fdb82a9338a60609ee5f9"
},
"Permission": "FULL_CONTROL"
}
]
}

... где перечислены все owner-ы файла. Итого (при такой ошибке) нужно перезалить файл с owner-ом аккаунта, откуда идёт чтение, либо изменить (добавить) owner-а или же переключаться в роль аккаунта, где есть права для операции чтения.

#s3_debug
🔥1
Стэк для VPC peering должен быть в том же регионе (cross-region появился в конце 2017), где находится VpcId:

peerManagementVpc4:
Type: 'AWS::EC2::VPCPeeringConnection'
Properties:
VpcId: !Ref VpcManagement
PeerVpcId: !Ref Vpc4
PeerOwnerId: !Ref AwsAccountVpc4
PeerRoleArn: !Ref RoleInVpc4

т.к. #CloudFormation ищет VpcId именно в этом регионе (аккаунте), а в шаблоне (т.е. в самом CloudFormation #templates) нет возможности задать регион (как минимум - пока).

В результате при попытке это сделать через шаблон будет #error:
VpcPeeringConnection failed to stabilize

А потому #cross_region #vpc_peering пока можно сделать лишь вручную через консоль (где есть возможность задать #aws_region).
You reached the quota on quotas

У анонсированного ранее #service_quotas тоже есть свои #лимиты и потому при активных попытках повысить ваши текущие квоты, можно получить #error:

An error occurred (QuotaExceededException) when calling the RequestServiceQuotaIncrease operation: This account has reached the maximum number of open service quota increase (SQI) requests. Before opening another SQI request, wait for an open SQI request to be accepted or rejected.

#lim(lim)
Ошибка CloudFront - Status Code: 409; Error Code: CNAMEAlreadyExists

Одна из (не)весёлых ситуаций. Вы создаете себе #CloudFront на свой родной тёплый ламповый домен и вдруг #error:

One or more aliases specified for the distribution includes an incorrectly configured DNS record that points to another CloudFront distribution. You must update the DNS record to correct the problem. For more information, see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-restrictions (Service: AmazonCloudFront; Status Code: 409; Error Code: CNAMEAlreadyExists; Request ID: a679d06c-aaee-11e9-8a2d-edaa84658d9b)

Как? Что? Где? Когда??? Кто сидел на моей кровати?!? Мой домен — кто мог создать на него дистрибуцию???

Нервный гуглинг вас приведёт на официальную страницу данной проблемы:

https://aws.amazon.com/premiumsupport/knowledge-center/resolve-cnamealreadyexists-error/

Там красиво всё. Объяснения причины - кто же занял ваш домен - найти не получится. А прочитав последний пункт мазохисты получат истинное удовольствие:

3. After the TXT record is created and you've added an SSL certificate to the distribution, contact AWS Support.

— Што-а-а?!??? У вас косяк, а мне в саппорт?!?

И, кстати, да - это возможно лишь при наличии платной подписки. Занавес.

===

Расслабтесь. В Амазоне не всё работает как должно. Да оно вам и не должно.

Обозначенная проблема имеет простое решение, включать временно платную подписку для обращения в саппорт (да, так можно) не потребуется. Просто создайте дистрибуцию БЕЗ (совсем) CNAME. А после создания добавьте нужный CNAME. Всё - просто в два этапа, а не сразу (как, в принципе, должно и раньше могло работать).

Почему сразу не срабатывает - это к Амазону (в техподдержку). Конечно, беда, если это нужно делать в CloudFormation шаблоне - придётся наворачивать костыли с разбиением на этапы создания плюс обновления. Но решить можно без хитрых спеллов и челобитной.

#i_love_aws
Башеписание в UserData

При использовании сложных баш-конструкций в CloudFormation UserData типа:

UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
CurZone=$(curl https://instance-data/latest/meta-data/placement/availability-zone)
CurRegion=${CurZone:0:${#CurZone} - 1}


Строчка CurRegion=${CurZone:0:${#CurZone} - 1} даст #error:

Template error: variable names in Fn::Sub syntax must contain only alphanumeric characters, underscores, periods, and colons.

Для правильного написания таких вещей, переменные нужно экранировать восклицательным знаком, как указано в документации:

To write a dollar sign and curly braces (${}) literally, add an exclamation point (!) after the open curly brace, such as ${!Literal}. AWS CloudFormation resolves this text as ${Literal}.

То есть правильное написание проблемной строки должно быть таким:

CurRegion=${!CurZone:0:${!#CurZone} - 1}

Однако в общем случае стоит избегать подобных сложностей в UserData, а ещё лучше, для конкретного этого примера, использовать встроенную переменную ${AWS::Region}.

#CloudFormation #UserData