def test_cfn_main_s3(): class MyCFNMain(CFNMain): def create_stack(self): return Stack(name='teststack') os.mkdir('data') aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): aws_env.client('cloudformation', region='us-east-1') stubber = aws_env.stub('cloudformation') stubber.add_response('validate_template', {}, {'TemplateURL': ANY}) stubber.add_response('create_stack', {}, { 'Capabilities': ['CAPABILITY_IAM'], 'StackName': 'teststack', 'TemplateURL': ANY }) stubber.add_response('describe_stacks', {}, {'StackName': 'teststack'}) aws_env.client('s3', region='us-east-1') s3_stubber = aws_env.stub('s3') s3_stubber.add_response( 'put_object', DEFAULT_S3_ANSWER, { 'Bucket': 'superbucket', 'Body': ANY, 'Key': ANY, 'ServerSideEncryption': 'AES256' }) with stubber: with s3_stubber: m = MyCFNMain(regions=['us-east-1'], data_dir='data', s3_bucket='superbucket', s3_key='test_key') m.execute(args=['push'], aws_env=aws_env)
def test_ls_ami(): """List AMIS from all regions.""" aws_env = AWSEnv(regions=['us-east-1', 'eu-west-1'], stub=True) stub_us = aws_env.stub('ec2', region='us-east-1') stub_eu = aws_env.stub('ec2', region='eu-west-1') stub_eu.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, { 'Filters': [], 'Owners': ['self'] }) stub_us.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-5678', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, { 'Filters': [], 'Owners': ['self'] }) assert len(AMI.ls()) == 2
def test_cfn_main_multiple_stacks(): class MyCFNMain(CFNMain): def create_stack(self): return [Stack(name="first-stack"), Stack(name="second-stack")] aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): aws_env.client("cloudformation", region="us-east-1") stubber = aws_env.stub("cloudformation") for stack_name in ("first-stack", "second-stack"): stubber.add_response("validate_template", {}, {"TemplateBody": ANY}) stubber.add_response( "create_stack", {}, { "Capabilities": ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"], "StackName": f"{stack_name}", "TemplateBody": ANY, }, ) stubber.add_response("describe_stacks", {}, {"StackName": f"{stack_name}"}) with stubber: m = MyCFNMain(regions=["us-east-1"]) m.execute(args=["push", "--no-wait"], aws_env=aws_env)
def test_cfn_main() -> None: class MyCFNMain(CFNMain): def create_stack(self) -> Stack: return Stack(name="teststack") aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): aws_env.client("cloudformation", region="us-east-1") stubber = aws_env.stub("cloudformation") stubber.add_response("validate_template", {}, {"TemplateBody": ANY}) stubber.add_response( "create_stack", {}, { "Capabilities": ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"], "StackName": "teststack", "ClientRequestToken": ANY, "TemplateBody": ANY, }, ) stubber.add_response("describe_stacks", {}, {"StackName": "teststack"}) with stubber: m = MyCFNMain(regions=["us-east-1"]) m.execute(args=["push", "--no-wait"], aws_env=aws_env)
def test_create_instance(): aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', {'Images': [{'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1'}]}, {'ImageIds': ANY}) i = Instance('testmachine', AMI('ami-1234'), disk_size=20) assert i.properties i.add(EphemeralDisk('/dev/sdb', 0)) assert i.properties vpc = VPC('VPC', '10.10.0.0/16') subnet = Subnet('Subnet', vpc, '10.10.10.0/24') subnet = Subnet('Subnet2', vpc, '10.10.20.0/24') security_group = SecurityGroup('mysgroup', vpc) i.add(NetworkInterface(subnet, description='first network interface')) i.add(NetworkInterface(subnet, groups=[security_group], description='2nd network interface')) i.add(NetworkInterface(subnet, groups=[security_group], description='3rd network interface', device_index=3)) assert i.properties with pytest.raises(AssertionError): i.add("non valid ec2 device")
def test_ls_ami(): """List AMIS from all regions.""" aws_env = AWSEnv(regions=["us-east-1", "eu-west-1"], stub=True) stub_us = aws_env.stub("ec2", region="us-east-1") stub_eu = aws_env.stub("ec2", region="eu-west-1") stub_eu.add_response( "describe_images", { "Images": [ {"ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": []} ] }, {"Filters": [], "Owners": ["self"]}, ) stub_us.add_response( "describe_images", { "Images": [ {"ImageId": "ami-5678", "RootDeviceName": "/dev/sda1", "Tags": []} ] }, {"Filters": [], "Owners": ["self"]}, ) assert len(AMI.ls()) == 2
def test_create_fortress_no_bastion(): aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, {'ImageIds': ANY}) stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, {'ImageIds': ANY}) d = PolicyDocument().append( Allow(to='s3:GetObject', on=['arn:aws:s3:::mybucket', 'arn:aws:s3:::mybucket/*'])) p = Policy('InternalPolicy', d) f = Fortress('myfortress', bastion_ami=None, internal_server_policy=p) f += Bucket('Bucket2') # Allow access to mybucket through a s3 endpoint f.private_subnet.add_bucket_access(['mybucket', f['Bucket2']]) # allow https f.add_network_access('https') f.add_private_server(AMI('ami-1234'), ['server1', 'server2']) assert f.body
def test_win_user_data_creation(): """Test creation of windows user data.""" a = WinUserData() a.add("powershell", 'echo "test powezrshell"') a.add("script", "echo test script") assert yaml.dump(a.properties) aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [ { "ImageId": "ami-1234-win", "RootDeviceName": "/dev/sda1", "Platform": "windows", "Tags": [], } ] }, {"ImageIds": ANY}, ) i = Instance("testmachine", AMI("ami-1234-win")) i.add_user_data("persist", "true") assert i.properties
def test_create_fortress(enable_github, requests_mock): if enable_github: requests_mock.get("https://api.github.com/meta", json=GITHUB_API_RANGE) requests_mock.get("https://ip-ranges.amazonaws.com/ip-ranges.json", json=AWS_IP_RANGES) aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [{ "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [] }] }, {"ImageIds": ANY}, ) stub.add_response( "describe_images", { "Images": [{ "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [] }] }, {"ImageIds": ANY}, ) d = PolicyDocument().append( Allow( to="s3:GetObject", on=["arn:aws:s3:::mybucket", "arn:aws:s3:::mybucket/*"], )) p = Policy("InternalPolicy", d) f = Fortress( "myfortress", allow_ssh_from="0.0.0.0/0", bastion_ami=AMI("ami-1234"), internal_server_policy=p, ) f += Bucket("Bucket2") # Allow access to mybucket through a s3 endpoint f.private_subnet.add_bucket_access(["mybucket", f["Bucket2"]]) # Allow access to a secret throught a secretsmanager endpoint f.add_secret_access("arn_secret") # Allow access to lambdas throught lambda endpoints f.add_secret_access(["arn_lambda_1", "arn_lambda_2"]) # allow https f.add_network_access("https") f.add_private_server(AMI("ami-1234"), ["server1", "server2"], github_access=enable_github) assert f.body
def test_cfn_main_s3() -> None: class MyCFNMain(CFNMain): def create_stack(self) -> Stack: return Stack(name="teststack") os.mkdir("data") aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): aws_env.client("cloudformation", region="us-east-1") stubber = aws_env.stub("cloudformation") stubber.add_response("validate_template", {}, {"TemplateURL": ANY}) stubber.add_response( "create_stack", {}, { "Capabilities": ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"], "StackName": "teststack", "ClientRequestToken": ANY, "TemplateURL": ANY, }, ) stubber.add_response("describe_stacks", {}, {"StackName": "teststack"}) aws_env.client("s3", region="us-east-1") s3_stubber = aws_env.stub("s3") s3_stubber.add_response( "put_object", DEFAULT_S3_ANSWER, { "Bucket": "superbucket", "Body": ANY, "Key": ANY, "ServerSideEncryption": "AES256", }, ) with stubber: with s3_stubber: m = MyCFNMain( regions=["us-east-1"], data_dir="data", s3_bucket="superbucket", s3_key="test_key", ) m.execute(args=["push", "--no-wait"], aws_env=aws_env)
def test_create_fortress_no_bastion(): aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [{ "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [] }] }, {"ImageIds": ANY}, ) stub.add_response( "describe_images", { "Images": [{ "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [] }] }, {"ImageIds": ANY}, ) d = PolicyDocument().append( Allow( to="s3:GetObject", on=["arn:aws:s3:::mybucket", "arn:aws:s3:::mybucket/*"], )) p = Policy("InternalPolicy", d) f = Fortress("myfortress", bastion_ami=None, internal_server_policy=p) f += Bucket("Bucket2") # Allow access to mybucket through a s3 endpoint f.private_subnet.add_bucket_access(["mybucket", f["Bucket2"]]) # Allow access to a secret throught a secretsmanager endpoint f.add_secret_access("arn_secret") # allow https f.add_network_access("https") f.add_private_server(AMI("ami-1234"), ["server1", "server2"]) assert f.body
def test_create_instance(): aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [ {"ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": []} ] }, {"ImageIds": ANY}, ) i = Instance("testmachine", AMI("ami-1234"), disk_size=20) assert i.properties i.add(EphemeralDisk("/dev/sdb", 0)) assert i.properties i.add(EBSDisk("/dev/sdc", size=20, encrypted=True)) assert i.properties vpc = VPC("VPC", "10.10.0.0/16") subnet = Subnet("Subnet", vpc, "10.10.10.0/24") subnet = Subnet("Subnet2", vpc, "10.10.20.0/24") security_group = SecurityGroup("mysgroup", vpc) i.add(EC2NetworkInterface(subnet, description="first network interface")) i.add( EC2NetworkInterface( subnet, groups=[security_group], description="2nd network interface" ) ) i.add( EC2NetworkInterface( subnet, groups=[security_group], description="3rd network interface", device_index=3, ) ) assert i.properties with pytest.raises(AssertionError): i.add("non valid ec2 device")
def test_cfn_init_set(): s = Stack(name='teststack') aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, {'ImageIds': ANY}) s += Instance('server', AMI('ami-1234')) s['server'].set_cfn_init(s) assert s.body
def test_run(capfd: CaptureFixture) -> None: """Test AWS session run method.""" aws_env = AWSEnv(regions=["us-east-1"], stub=True) stubber = aws_env.stub("sts") # 2 calls to cli_cmd are made in this test for _ in range(2): stubber.add_response( "assume_role", { "Credentials": { "AccessKeyId": "12345678912345678", "SecretAccessKey": "12345678912345678", "SessionToken": "12345678912345678", "Expiration": datetime(4042, 1, 1), } }, { "RoleArn": "arn:aws:iam::123456789123:role/TestRole", "RoleSessionName": "aws_run_session", "DurationSeconds": 7200, }, ) with stubber: p_right = aws_env.run( ["aws", "--version"], "arn:aws:iam::123456789123:role/TestRole", output=None, session_duration=7200, ) assert p_right.status == 0 captured = capfd.readouterr() assert captured.out.startswith("aws-cli/") with pytest.raises(AWSSessionRunError): p_wrong = aws_env.run( ["aws", "not_a_command"], "arn:aws:iam::123456789123:role/TestRole", output=None, session_duration=7200, ) assert p_wrong.status != 0
def test_cfn_init_set(): s = Stack(name="teststack") aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [ {"ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": []} ] }, {"ImageIds": ANY}, ) s += Instance("server", AMI("ami-1234")) s["server"].set_cfn_init() assert s.body
def test_docker_function(stack: Stack) -> None: """Test adding docker function to stack.""" aws_env = AWSEnv(regions=["us-east-1"], stub=True) stubber_ecr = aws_env.stub("ecr") stubber_ecr.add_response( "get_authorization_token", { "authorizationData": [{ "authorizationToken": base64.b64encode(b"test_user:test_pwd").decode(), "proxyEndpoint": "test_endpoint", }] }, {}, ) stack.deploy_session = aws_env docker_function = DockerFunction( name="dockerfunction", description="this is a test", role="somearn", source_dir=SOURCE_DIR, repository_name="e3_aws_test_repository", image_tag="test_tag", ) client = docker.from_env() try: stack.add(docker_function) except docker.errors.APIError: # Push is expected to fail pass finally: # Always try to remove local test image client.images.remove( f"e3_aws_test_repository:{docker_function.image_tag}") # Add resources without trying to push the image to ECR stack.dry_run = True stack.add(docker_function) assert stack.export()["Resources"] == EXPECTED_DOCKER_FUNCTION
def test_boto3() -> None: """Test boto3 session from Session.""" aws_env = AWSEnv(regions=["us-east-1"], stub=True) stubber = aws_env.stub("sts") with stubber: session = Session( regions=["us-east-1"], credentials={ "AccessKeyId": "AK_test", "SecretAccessKey": "SA_test", "SessionToken": "ST_test", }, ) boto3_session = session.to_boto3() boto3_creds = boto3_session.get_credentials().get_frozen_credentials() assert boto3_creds.access_key == "AK_test" assert boto3_creds.secret_key == "SA_test" assert boto3_creds.token == "ST_test"
def test_cfn_main(): class MyCFNMain(CFNMain): def create_stack(self): return Stack(name='teststack') aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): aws_env.client('cloudformation', region='us-east-1') stubber = aws_env.stub('cloudformation') stubber.add_response('validate_template', {}, {'TemplateBody': ANY}) stubber.add_response('create_stack', {}, { 'Capabilities': ['CAPABILITY_IAM'], 'StackName': 'teststack', 'TemplateBody': ANY }) stubber.add_response('describe_stacks', {}, {'StackName': 'teststack'}) with stubber: m = MyCFNMain(regions=['us-east-1']) m.execute(args=['push'], aws_env=aws_env)
def test_user_data_creation(): """Test creation of user data.""" a = UserData() a.add('toto.txt', 'x-shellscript', 'Hello') a.add('url1', 'x-include-url', 'toto.jpg') assert yaml.dump(a.properties) aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [] }] }, {'ImageIds': ANY}) i = Instance('testmachine', AMI('ami-1234')) i.add_user_data('url1', 'x-include-url', 'http://dummy') assert i.properties
def test_win_user_data_creation(): """Test creation of windows user data.""" a = WinUserData() a.add('powershell', 'echo "test powezrshell"') a.add('script', 'echo test script') assert yaml.dump(a.properties) aws_env = AWSEnv(regions=['us-east-1'], stub=True) with default_region('us-east-1'): stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1234-win', 'RootDeviceName': '/dev/sda1', 'Platform': 'windows', 'Tags': [] }] }, {'ImageIds': ANY}) i = Instance('testmachine', AMI('ami-1234-win')) i.add_user_data('persist', 'true') assert i.properties
def test_user_data_creation(): """Test creation of user data.""" a = UserData() a.add("toto.txt", "x-shellscript", "Hello") a.add("url1", "x-include-url", "toto.jpg") assert yaml.dump(a.properties) aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [ {"ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": []} ] }, {"ImageIds": ANY}, ) i = Instance("testmachine", AMI("ami-1234")) i.add_user_data("url1", "x-include-url", "http://dummy") assert i.properties
def test_create_fortress_with_too_much_sgs(): aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [{ "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [] }] }, {"ImageIds": ANY}, ) d = PolicyDocument().append( Allow( to="s3:GetObject", on=["arn:aws:s3:::mybucket", "arn:aws:s3:::mybucket/*"], )) p = Policy("InternalPolicy", d) f = Fortress("myfortress", bastion_ami=None, internal_server_policy=p) # Adding 16 extra security groups should raise an exception (The maximum # number of security groups is 16 and there is a default InternalSG) sg_groups = [ SecurityGroup(name=f"sg{id}", vpc=f.vpc.vpc) for id in range(16) ] with pytest.raises(AWSFortressError): f.add_private_server( AMI("ami-1234"), ["server1"], amazon_access=False, github_access=False, extra_groups=sg_groups, )
def test_cfn_main_push_existing_stack(status: Tuple[str, str, int], monkeypatch: MonkeyPatch) -> None: """Test pushing an already existing stack. :param status: Tuple with status and status reason from describe_change_set response and associated expected execute return value. """ class MyCFNMain(CFNMain): def create_stack(self): return [Stack(name="existing-stack")] aws_env = AWSEnv(regions=["us-east-1"], stub=True) with default_region("us-east-1"): aws_env.client("cloudformation", region="us-east-1") stack_name = "existing-stack" stubber = aws_env.stub("cloudformation") stubber.add_response("validate_template", {}, {"TemplateBody": ANY}) stubber.add_response( "describe_stacks", service_response={ "Stacks": [{ "StackName": stack_name, "CreationTime": datetime(2016, 1, 20, 22, 9), "StackStatus": "CREATE_COMPLETE", "StackId": stack_name + "1", }] }, expected_params={"StackName": stack_name}, ) stubber.add_response( "create_change_set", {}, { "Capabilities": ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"], "ChangeSetName": ANY, "StackName": stack_name, "TemplateBody": ANY, }, ) stubber = stubber stubber.add_response( "describe_change_set", { "StackName": stack_name, "Status": status[0], "StatusReason": status[1], "Changes": [], }, { "ChangeSetName": ANY, "StackName": stack_name }, ) if status[0] == "FAILED": stubber.add_response("delete_change_set", {}, { "ChangeSetName": ANY, "StackName": stack_name }) else: stubber.add_response( "execute_change_set", {}, { "ChangeSetName": ANY, "StackName": ANY, "ClientRequestToken": ANY }, ) stubber.add_response( "describe_stacks", service_response={ "Stacks": [{ "StackName": stack_name, "CreationTime": datetime(2016, 1, 20, 22, 9), "StackStatus": "UPDATE_COMPLETE", "StackId": stack_name + "1", }] }, expected_params={"StackName": ANY}, ) monkeypatch.setattr("builtins.input", lambda _: "Y") with stubber: m = MyCFNMain(regions=["us-east-1"]) assert m.execute(args=["update", "--no-wait"], aws_env=aws_env) == status[2]
def test_select(): """Test AMI.select.""" aws_env = AWSEnv(regions=["us-east-1"], stub=True) stub = aws_env.stub("ec2", region="us-east-1") stub.add_response( "describe_images", { "Images": [ { "ImageId": "ami-1", "RootDeviceName": "/dev/sda1", "Tags": [ {"Key": "platform", "Value": "x86_64-linux"}, {"Key": "os_version", "Value": "suse11"}, {"Key": "timestamp", "Value": "4"}, ], }, { "ImageId": "ami-2", "RootDeviceName": "/dev/sda1", "Tags": [ {"Key": "platform", "Value": "x86_64-linux"}, {"Key": "os_version", "Value": "suse11"}, {"Key": "timestamp", "Value": "5"}, ], }, { "ImageId": "ami-3", "RootDeviceName": "/dev/sda1", "Tags": [ {"Key": "platform", "Value": "x86_64-linux"}, {"Key": "os_version", "Value": "suse11"}, {"Key": "timestamp", "Value": "1"}, ], }, { "ImageId": "ami-4", "RootDeviceName": "/dev/sda1", "Tags": [ {"Key": "platform", "Value": "x86_64-linux"}, {"Key": "timestamp", "Value": "1"}, ], }, { "ImageId": "ami-1234", "RootDeviceName": "/dev/sda1", "Tags": [ {"Key": "platform", "Value": "x86_64-linux"}, {"Key": "os_version", "Value": "ubuntu16.04"}, {"Key": "timestamp", "Value": "1"}, ], }, ] }, { "Filters": [ {"Name": "tag-key", "Values": ["platform"]}, {"Name": "tag-key", "Values": ["timestamp"]}, {"Name": "tag-key", "Values": ["os_version"]}, ], "Owners": ["self"], }, ) with default_region("us-east-1"): ami = AMI.select(platform="x86_64-linux", os_version="suse11") assert ami.id == "ami-2"
def test_select(): """Test AMI.select.""" aws_env = AWSEnv(regions=['us-east-1'], stub=True) stub = aws_env.stub('ec2', region='us-east-1') stub.add_response( 'describe_images', { 'Images': [{ 'ImageId': 'ami-1', 'RootDeviceName': '/dev/sda1', 'Tags': [{ 'Key': 'platform', 'Value': 'x86_64-linux' }, { 'Key': 'os_version', 'Value': 'suse11' }, { 'Key': 'timestamp', 'Value': '4' }] }, { 'ImageId': 'ami-2', 'RootDeviceName': '/dev/sda1', 'Tags': [{ 'Key': 'platform', 'Value': 'x86_64-linux' }, { 'Key': 'os_version', 'Value': 'suse11' }, { 'Key': 'timestamp', 'Value': '5' }] }, { 'ImageId': 'ami-3', 'RootDeviceName': '/dev/sda1', 'Tags': [{ 'Key': 'platform', 'Value': 'x86_64-linux' }, { 'Key': 'os_version', 'Value': 'suse11' }, { 'Key': 'timestamp', 'Value': '1' }] }, { 'ImageId': 'ami-4', 'RootDeviceName': '/dev/sda1', 'Tags': [{ 'Key': 'platform', 'Value': 'x86_64-linux' }, { 'Key': 'timestamp', 'Value': '1' }] }, { 'ImageId': 'ami-1234', 'RootDeviceName': '/dev/sda1', 'Tags': [{ 'Key': 'platform', 'Value': 'x86_64-linux' }, { 'Key': 'os_version', 'Value': 'ubuntu16.04' }, { 'Key': 'timestamp', 'Value': '1' }] }] }, { 'Filters': [{ 'Name': 'tag-key', 'Values': ['platform'] }, { 'Name': 'tag-key', 'Values': ['timestamp'] }, { 'Name': 'tag-key', 'Values': ['os_version'] }], 'Owners': ['self'] }) with default_region('us-east-1'): ami = AMI.select(platform='x86_64-linux', os_version='suse11') assert ami.id == 'ami-2'