213 lines
5.7 KiB
Python
213 lines
5.7 KiB
Python
|
from uuid import uuid4
|
||
|
|
||
|
import boto3
|
||
|
import pytest
|
||
|
from botocore.exceptions import ClientError
|
||
|
|
||
|
from . import cloudformation_aws_verified
|
||
|
|
||
|
conditional_output_conditional_value = """
|
||
|
Outputs:
|
||
|
roleArn:
|
||
|
Condition: RoleCondition
|
||
|
Value: !GetAtt role.Arn
|
||
|
|
||
|
Parameters:
|
||
|
roleName:
|
||
|
Type: String
|
||
|
Description: Predefined role name
|
||
|
|
||
|
Conditions:
|
||
|
RoleCondition: !Equals [ !Ref roleName, "myrole" ]
|
||
|
|
||
|
Resources:
|
||
|
role:
|
||
|
Condition: RoleCondition
|
||
|
Type: 'AWS::IAM::Role'
|
||
|
Properties:
|
||
|
AssumeRolePolicyDocument:
|
||
|
Version: 2012-10-17
|
||
|
Statement:
|
||
|
- Effect: Allow
|
||
|
Principal:
|
||
|
Service:
|
||
|
- ec2.amazonaws.com
|
||
|
Action:
|
||
|
- 'sts:AssumeRole'
|
||
|
"""
|
||
|
|
||
|
|
||
|
@pytest.mark.aws_verified
|
||
|
@cloudformation_aws_verified()
|
||
|
def test_conditional_output_conditional_value():
|
||
|
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "myrole"}]
|
||
|
name = f"stack{str(uuid4())[0:6]}"
|
||
|
cf.create_stack(
|
||
|
StackName=name,
|
||
|
TemplateBody=conditional_output_conditional_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
waiter = cf.get_waiter("stack_create_complete")
|
||
|
waiter.wait(StackName=name)
|
||
|
|
||
|
stack = cf.describe_stacks(StackName=name)["Stacks"][0]
|
||
|
assert stack["Outputs"][0]["OutputKey"] == "roleArn"
|
||
|
|
||
|
cf.delete_stack(StackName=name)
|
||
|
|
||
|
# verify role does not exist with different name
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "diffname"}]
|
||
|
cf.create_stack(
|
||
|
StackName=f"{name}2",
|
||
|
TemplateBody=conditional_output_conditional_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
waiter = cf.get_waiter("stack_create_complete")
|
||
|
waiter.wait(StackName=f"{name}2")
|
||
|
stack = cf.describe_stacks()["Stacks"][0]
|
||
|
assert "Outputs" not in stack
|
||
|
|
||
|
cf.delete_stack(StackName=f"{name}2")
|
||
|
|
||
|
|
||
|
permanent_output_conditional_value = """
|
||
|
Outputs:
|
||
|
roleArn:
|
||
|
Value: !GetAtt role.Arn
|
||
|
|
||
|
Parameters:
|
||
|
roleName:
|
||
|
Type: String
|
||
|
Description: Predefined role name
|
||
|
|
||
|
Conditions:
|
||
|
RoleCondition: !Equals [ !Ref roleName, "myrole" ]
|
||
|
|
||
|
Resources:
|
||
|
role:
|
||
|
Condition: RoleCondition
|
||
|
Type: 'AWS::IAM::Role'
|
||
|
Properties:
|
||
|
AssumeRolePolicyDocument:
|
||
|
Version: 2012-10-17
|
||
|
Statement:
|
||
|
- Effect: Allow
|
||
|
Principal:
|
||
|
Service:
|
||
|
- ec2.amazonaws.com
|
||
|
Action:
|
||
|
- 'sts:AssumeRole'
|
||
|
"""
|
||
|
|
||
|
|
||
|
@pytest.mark.aws_verified
|
||
|
@cloudformation_aws_verified()
|
||
|
def test_permanent_output_conditional_value():
|
||
|
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "myrole"}]
|
||
|
|
||
|
name = f"stack{str(uuid4())[0:6]}"
|
||
|
cf.create_stack(
|
||
|
StackName=name,
|
||
|
TemplateBody=permanent_output_conditional_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
waiter = cf.get_waiter("stack_create_complete")
|
||
|
waiter.wait(StackName=name)
|
||
|
|
||
|
# Works - because role exists
|
||
|
stack = cf.describe_stacks(StackName=name)["Stacks"][0]
|
||
|
assert stack["Outputs"][0]["OutputKey"] == "roleArn"
|
||
|
|
||
|
cf.delete_stack(StackName=name)
|
||
|
|
||
|
# Role does not exist with different name
|
||
|
# So we can't get the Output either
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "diffname"}]
|
||
|
with pytest.raises(ClientError) as exc:
|
||
|
cf.create_stack(
|
||
|
StackName=f"{name}2",
|
||
|
TemplateBody=permanent_output_conditional_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
err = exc.value.response["Error"]
|
||
|
assert err["Code"] == "ValidationError"
|
||
|
assert (
|
||
|
err["Message"]
|
||
|
== "Unresolved resource dependencies [role] in the Outputs block of the template"
|
||
|
)
|
||
|
|
||
|
|
||
|
conditional_output_of_permanent_value = """
|
||
|
Outputs:
|
||
|
roleArn:
|
||
|
Condition: RoleCondition
|
||
|
Value: !GetAtt role.Arn
|
||
|
|
||
|
Parameters:
|
||
|
roleName:
|
||
|
Type: String
|
||
|
Description: Predefined role name
|
||
|
|
||
|
Conditions:
|
||
|
RoleCondition: !Equals [ !Ref roleName, "myrole" ]
|
||
|
|
||
|
Resources:
|
||
|
role:
|
||
|
Type: 'AWS::IAM::Role'
|
||
|
Properties:
|
||
|
AssumeRolePolicyDocument:
|
||
|
Version: 2012-10-17
|
||
|
Statement:
|
||
|
- Effect: Allow
|
||
|
Principal:
|
||
|
Service:
|
||
|
- ec2.amazonaws.com
|
||
|
Action:
|
||
|
- 'sts:AssumeRole'
|
||
|
"""
|
||
|
|
||
|
|
||
|
@pytest.mark.aws_verified
|
||
|
@cloudformation_aws_verified()
|
||
|
def test_conditional_output_of_permanent_value():
|
||
|
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "myrole"}]
|
||
|
|
||
|
name = f"stack{str(uuid4())[0:6]}"
|
||
|
cf.create_stack(
|
||
|
StackName=name,
|
||
|
TemplateBody=conditional_output_of_permanent_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
waiter = cf.get_waiter("stack_create_complete")
|
||
|
waiter.wait(StackName=name)
|
||
|
|
||
|
stack = cf.describe_stacks(StackName=name)["Stacks"][0]
|
||
|
assert stack["Outputs"][0]["OutputKey"] == "roleArn"
|
||
|
|
||
|
cf.delete_stack(StackName=name)
|
||
|
|
||
|
# verify role does not exist with different name
|
||
|
param = [{"ParameterKey": "roleName", "ParameterValue": "diffname"}]
|
||
|
cf.create_stack(
|
||
|
StackName=f"{name}2",
|
||
|
TemplateBody=conditional_output_of_permanent_value,
|
||
|
Parameters=param,
|
||
|
Capabilities=["CAPABILITY_IAM"],
|
||
|
)
|
||
|
waiter = cf.get_waiter("stack_create_complete")
|
||
|
waiter.wait(StackName=f"{name}2")
|
||
|
stack = cf.describe_stacks(StackName=f"{name}2")["Stacks"][0]
|
||
|
# The Role does exist
|
||
|
# But Output is conditional, and just doesn't return anything
|
||
|
assert "Outputs" not in stack
|
||
|
|
||
|
cf.delete_stack(StackName=f"{name}2")
|