Dzisiaj przyjrzymy się jak zarządzać tagami na poziomie konta oraz całej Organizacji AWS na kilku przykładach.
Tagi
Słowem wstępu czym w ogóle są tagi i do czego możemy je wykorzystać. Tagi to po prostu metadane w postaci klucz i wartość, które można przypiąć do większości zasobów w chmurze AWS.
Jako metadane mogą być wykorzystywane w bardzo wielu miejscach, takich jak Cost Explorer, by określić jaki jest koszt wszystkich zasobów z danym tagiem. Określić z jakiego typu środowiskiem, czy jaką wersją mamy do czynienia, a nawet opisywać kto jest właścicielem danego zasobu. Więcej o strategiach tagowania zasobów możesz przeczytać tutaj.
Mamy kilka możliwości, jak nakładać ramy na sposób tagowania zasobów w obrębie organizacji lub konta.
Tag Policies
Jednym z mechanizmów w usłudze AWS Organizations są Tag Policies. Uruchamiane są zawsze, gdy wykonujemy akcje, które dotykają tagów. W praktyce oznacza to, że jesteśmy w stanie wymusić wielkość liter czy dozwolone wartości oraz zaznaczyć dla jakich zasobów aplikujemy te reguły, ale nie jesteśmy w stanie wymusić istnienia danego taga.
Do czego może się przydać taka polityka?
Scenariusz
Posiadamy trzy konta w organizacji: Development, Staging oraz Production. Wszystkie zasoby w ramach tych kont posiadają tag environment-type, który przyjmuje jedną z trzech wartości:
- dev
- stage
- prod
Potrzeba
Obronić się przed wdrożeniem aplikacji w złej wersji na dane konto.
Rozwiązanie
Dla danego konta powinna być dozwolona tylko jedna wartość taga environment-type.
Jak w takim razie dodać taką politykę?
Po pierwsze musimy pozwolić na używanie Tag policies w ramach organizacji. By to zrobić wejdź w AWS Organizations, a następnie w Settings.

Na kolejnym ekranie zezwól na Tag policies.

Następnie utwórzmy politykę dla konta Production klikając “Create policy”.

Teraz podajemy nazwę tagu.
Pierwszy checkbox zapewnia weryfikację wielkości liter.
Następnie podajemy jakie wartości mają być dostępne, w tym przypadku tylko “prod”.

W ostatnim polu wybieramy dla jakich zasobów polityka będzie wymagana, w tym przypadku możemy zaznaczyć wszystkie. Jeśli nie wybierzemy żadnego zasobu, to polityka nie będzie wymuszona, czyli zasoby jej nie spełniające nadal będą mogły być utworzone. Do czego wykorzystać taką politykę dowiesz się później.
{
"tags": {
"environment-type": {
"tag_key": {
"@@assign": "environment-type"
},
"tag_value": {
"@@assign": [
"prod"
]
},
"enforced_for": {
"@@assign": [
"apigateway:apikeys",
"...",
"workspaces:*"
]
}
}
}
}
Przygotowaną politykę musimy zaaplikować do konta, jednostki organizacji lub konta root. O dziedziczeniu polityk więcej można przeczytać tutaj.

W przytoczonym scenariuszu politykę oczywiście przypniemy do konta “Production” oraz utworzymy dwie kolejne dla kont “Development” oraz “Staging”.
Co się stanie jeśli zostanie złamana nałożona polityka? Otóż zasób nie zostanie utworzony, a w CloudFormation uzyskamy jeden z poniższych błędów.


Resource Groups
Tag policy można wykorzystać również do zlokalizowania zasobów aktualnie posiadających niezgodne tagi. Służy do tego usługa Resource Groups, a dokładnie zawarty w niej moduł Tag policies.


Service Control Policies
Innym mechanizmem, który możemy wykorzystać do pracy z tagami są Service Control Policies. Ich zastosowanie jest o wiele szersze, ale skupmy się na jednym scenariuszu.
Scenariusz
Posiadamy konto AWS, na którym działa wiele aplikacji. Chcemy mieć możliwość przejrzenia ile kosztują poszczególne aplikacje.
Potrzeba
Każdy zasób musi posiadać tag “service-name”.
Rozwiązanie
Wymusić tag “service-name” podczas tworzenia CloudFormation.
Dodajmy w takim razie taką politykę.
Przejdźmy teraz do edycji polityk tagów.

Utwórzmy politykę klikając “Create policy”.

Następnie zajmujemy się samą polityką. Można do tego wykorzystać edytor wizualny albo ręcznie zmienić JSONa.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ServiceNameStatement",
"Effect": "Deny",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:CreateChangeSet"
],
"Resource": "arn:aws:cloudformation:*:*:stack/*/*",
"Condition": {
"Null": {
"aws:RequestTag/service-name": "true"
}
}
}
]
}
Przyjrzyjmy się poszczególnym elementom polityki.
Na początku definiujemy czy zezwalamy na jakąś operację, czy nie.
"Effect": "Deny"
Następnie definiujemy jakich akcji dotyczy polityka.
W naszym przypadku jest to utworzenie oraz uaktualnienie stacka CloudFormation, a także każde utworzenie ChangeSetu, ponieważ polecenia deploy z AWS CLI oraz SAM nie wywołują akcji CreateStack, czy UpdateStack.
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:CreateChangeSet"
]
Element Resource ustawiamy na wszystkie zasoby typu stack, ponieważ reguła ma być aplikowana dla każdego CloudFormation.
Nie możemy tutaj zastosować po prostu *, ponieważ pod zasoby cloudformation wchodzą również Transformaty, do których tagi nie są przekazywane.
"Resource": "arn:aws:cloudformation:*:*:stack/*/*"
Na koniec musimy ustawić warunek, kiedy reguła ma być aplikowana, czyli wymóg istnienia taga “service-name”.
Sprawdzamy, czy tag service-name istnieje w zapytaniu.
Więcej o składni Service Control Policy można przeczytać tutaj, a o warunkach tutaj.
"Condition": {
"Null": {
"aws:RequestTag/service-name": "true"
}
}
Po utworzeniu polityki zostaje przypisanie jej do konta tak samo jak robiliśmy to w przypadku Tag Policy.
Zostało przetestować działanie zaaplikowanej polityki.
Gdy wywołamy komendę aws cloudformation deploy bez podania tagów, otrzymamy poniższą odpowiedź, czyli brak dostępu.
aws cloudformation deploy
An error occurred (AccessDenied) when calling the CreateChangeSet operation:
User: arn:aws:sts::000000000000:assumed-role/RoleName is not authorized to perform:
cloudformation:CreateChangeSet on resource: arn:aws:cloudformation:eu-west-1:000000000000:stack/tag-policy-test/00000000-0000-0000-0000-000000000000 with an explicit deny
Niestety wiadomość o błędzie nie jest już tak przejrzysta, jak w przypadku Tag Policy, ale pozwala nałożyć dużo więcej restrykcji.
Dopiero dodanie taga do aws cloudformation deploy poskutkuje poprawnym wykonaniem polecenia.
aws cloudformation deploy --tag service-name=test