coveralls: 
[![Coverage Status](https://coveralls.io/builds/10978001/badge)](https://coveralls.io/builds/10978001)

Changes Unknown when pulling **81412ebca59282719b16c1387624a0d97cbc0348 on acm-createdat-key-error** into ** on master**.

hjacobs: :+1: 
diff --git a/senza/manaus/acm.py b/senza/manaus/acm.py
index 8d85313..f43ca8c 100644
--- a/senza/manaus/acm.py
+++ b/senza/manaus/acm.py
@@ -81,7 +81,7 @@ class ACMCertificate:
         subject_alternative_name = certificate['SubjectAlternativeNames']
         domain_validation_options = certificate['DomainValidationOptions']
         subject = certificate['Subject']
-        created_at = certificate['CreatedAt']
+        created_at = certificate.get('CreatedAt')
         status = certificate['Status']
         signature_algorithm = certificate['SignatureAlgorithm']
         in_use_by = certificate['InUseBy']

resolve_ssl_certificates for ACM: KeyError: 'CreatedAt'
```
cat /tmp/senza-traceback-28v30ylh
Traceback (most recent call last):
  File "/usr/lib/python3.5/site-packages/senza/error_handling.py", line 105, in __call__
    self.function(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.5/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.5/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/senza/cli.py", line 580, in create
    data = create_cf_template(definition, region, version, parameter, force, parameter_file)
  File "/usr/lib/python3.5/site-packages/senza/cli.py", line 669, in create_cf_template
    data = evaluate(definition.copy(), args, account_info, force)
  File "/usr/lib/python3.5/site-packages/senza/cli.py", line 237, in evaluate
    definition = componentfn(definition, configuration, args, info, force, account_info)
  File "/usr/lib/python3.5/site-packages/senza/components/weighted_dns_elastic_load_balancer.py", line 49, in component_weighted_dns_elastic_load_balancer
    account_info)
  File "/usr/lib/python3.5/site-packages/senza/components/elastic_load_balancer.py", line 135, in component_elastic_load_balancer
    listeners = resolve_ssl_certificates(listeners, subdomain, main_zone, account_info)
  File "/usr/lib/python3.5/site-packages/senza/components/elastic_load_balancer.py", line 95, in resolve_ssl_certificates
    ssl_cert = get_ssl_cert(subdomain, main_zone, listener, account_info)
  File "/usr/lib/python3.5/site-packages/senza/components/elastic_load_balancer.py", line 52, in get_ssl_cert
    reverse=True)
  File "/usr/lib/python3.5/site-packages/senza/manaus/acm.py", line 178, in get_certificates
    certificate = ACMCertificate.get_by_arn(self.region, arn)
  File "/usr/lib/python3.5/site-packages/senza/manaus/acm.py", line 110, in get_by_arn
    return cls.from_boto_dict(certificate)
  File "/usr/lib/python3.5/site-packages/senza/manaus/acm.py", line 84, in from_boto_dict
    created_at = certificate['CreatedAt']
KeyError: 'CreatedAt'
```

Imported certs don't have `CreatedAt`:
```
>>> c.describe_certificate(CertificateArn='arn:aws:acm:eu-central-1:123456789012:certificate/f14f9718-7da8-4250-9c21-d0341da4e44f')
{'Certificate': {'NotAfter': datetime.datetime(2017, 5, 7, 10, 0, tzinfo=tzlocal()), 'SubjectAlternativeNames': ['pierone.stups.zalan.do', 'registry.opensource.zalan.do'], 'Subject': 'C=DE,L=Berlin,O=Zalando SE,OU=CDP,CN=CDP Proxy', 'Serial': '2a:d2:f6:d3:23:62:0b:5f:f8:2f:d6:3a:4a:9f:b8:c6:48:a0:11:62', 'Type': 'IMPORTED', 'ImportedAt': datetime.datetime(2017, 4, 7, 10, 12, 55, tzinfo=tzlocal()), 'SignatureAlgorithm': 'SHA256WITHRSA', 'CertificateArn': 'arn:aws:acm:eu-central-1:123456789012:certificate/f14f9718-7da8-4250-9c21-d0341da4e44f', 'NotBefore': datetime.datetime(2017, 4, 7, 10, 0, tzinfo=tzlocal()), 'DomainValidationOptions': [{'DomainName': 'pierone.stups.zalan.do'}, {'DomainName': 'registry.opensource.zalan.do'}], 'Status': 'ISSUED', 'DomainName': 'pierone.stups.zalan.do', 'Issuer': 'Zalando SE', 'InUseBy': [], 'KeyAlgorithm': 'RSA-2048'}, 'ResponseMetadata': {'HTTPHeaders': {'content-type': 'application/x-amz-json-1.1', 'x-amzn-requestid': '514a08ad-1b71-11e7-91d6-c5bca103e8f9', 'date': 'Fri, 07 Apr 2017 09:05:16 GMT', 'content-length': '695'}, 'RequestId': '514a08ad-1b71-11e7-91d6-c5bca103e8f9', 'HTTPStatusCode': 200, 'RetryAttempts': 0}}
```
diff --git a/tests/fixtures.py b/tests/fixtures.py
index 2d91e42..ae21b24 100644
--- a/tests/fixtures.py
+++ b/tests/fixtures.py
@@ -20,7 +20,7 @@ CERT1_ZO_NE = {'CertificateArn': 'arn:aws:acm:eu-west-1:cert1',
                'IssuedAt': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                'Issuer': 'SenzaTest',
                'KeyAlgorithm': 'RSA-2048',
-               'NotAfter': datetime(2017, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
+               'NotAfter': datetime(2020, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                'NotBefore': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                'Serial': '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00',
                'SignatureAlgorithm': 'SHA256WITHRSA',
@@ -45,7 +45,7 @@ CERT1_ZO_NE_REVOKED = {'CertificateArn': 'arn:aws:acm:eu-west-1:cert1',
                        'IssuedAt': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                        'Issuer': 'SenzaTest',
                        'KeyAlgorithm': 'RSA-2048',
-                       'NotAfter': datetime(2017, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
+                       'NotAfter': datetime(2020, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                        'NotBefore': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
                        'Serial': '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00',
                        'SignatureAlgorithm': 'SHA256WITHRSA',
@@ -86,7 +86,7 @@ HOSTED_ZONE_ZO_NE_DEV = {'Config': {'PrivateZone': False},
 SERVER_CERT_ZO_NE = MagicMock(name='zo-ne')
 SERVER_CERT_ZO_NE.server_certificate_metadata = {'Arn': 'arn:aws:123',
                                                  'ServerCertificateName': 'zo-ne',
-                                                 'Expiration': datetime(2017, 4, 1, 12, 14, 14,
+                                                 'Expiration': datetime(2020, 4, 1, 12, 14, 14,
                                                                         tzinfo=timezone(timedelta(hours=2))),
                                                  'Path': '/',
                                                  'ServerCertificateId': '000',
diff --git a/tests/test_manaus/test_acm.py b/tests/test_manaus/test_acm.py
index f022ff2..a10013b 100644
--- a/tests/test_manaus/test_acm.py
+++ b/tests/test_manaus/test_acm.py
@@ -34,7 +34,7 @@ CERT1 = {'CertificateArn': 'arn:aws:acm:eu-west-1:cert1',
          'IssuedAt': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
          'Issuer': 'SenzaTest',
          'KeyAlgorithm': 'RSA-2048',
-         'NotAfter': datetime(2017, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
+         'NotAfter': datetime(2020, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
          'NotBefore': datetime(2016, 4, 1, 12, 14, 14, tzinfo=timezone.utc),
          'Serial': '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00',
          'SignatureAlgorithm': 'SHA256WITHRSA',
@@ -75,7 +75,7 @@ CERT2 = {'CertificateArn': 'arn:aws:acm:eu-west-1:cert2',
          'IssuedAt': datetime(2016, 4, 1, 12, 14, 14),
          'Issuer': 'SenzaTest',
          'KeyAlgorithm': 'RSA-2048',
-         'NotAfter': datetime(2017, 4, 1, 12, 14, 14),
+         'NotAfter': datetime(2020, 4, 1, 12, 14, 14),
          'NotBefore': datetime(2016, 4, 1, 12, 14, 14),
          'Serial': '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00',
          'SignatureAlgorithm': 'SHA256WITHRSA',
@@ -85,6 +85,23 @@ CERT2 = {'CertificateArn': 'arn:aws:acm:eu-west-1:cert2',
                                      '*.senza.aws.example.net',
                                      '*.app.example.net']}
 
+CERT3 = {
+        'NotAfter': datetime(2017, 5, 7, 10, 0, tzinfo=timezone.utc),
+        'SubjectAlternativeNames': ['pierone.stups.zalan.do', 'registry.opensource.zalan.do'],
+        'Subject': 'C=DE,L=Berlin,O=Zalando SE,OU=CDP,CN=CDP Proxy',
+        'Serial': '2a:d2:f6:d3:23:62:0b:5f:f8:2f:d6:3a:4a:9f:b8:c6:48:a0:11:62',
+        'Type': 'IMPORTED',
+        'ImportedAt': datetime(2017, 4, 7, 10, 12, 55, tzinfo=timezone.utc),
+        'SignatureAlgorithm': 'SHA256WITHRSA',
+        'CertificateArn': 'arn:aws:acm:eu-west-1:cert3',
+        'NotBefore': datetime(2017, 4, 7, 10, 0, tzinfo=timezone.utc),
+        'DomainValidationOptions': [{'DomainName': 'pierone.stups.zalan.do'}, {'DomainName': 'registry.opensource.zalan.do'}],
+        'Status': 'ISSUED',
+        'DomainName': 'pierone.stups.zalan.do',
+        'Issuer': 'Zalando SE',
+        'InUseBy': [],
+        'KeyAlgorithm': 'RSA-2048'}
+
 CERT_VALIDATION_TIMED_OUT = {
     'KeyAlgorithm': 'RSA-2048',
     'DomainName': 'alpha.example.org',
@@ -109,7 +126,7 @@ def test_certificate_valid():
     assert certificate1.domain_name == '*.senza.example.com'
     assert certificate1.is_valid(when=datetime(2016, 4, 5, 12, 14, 14,
                                                tzinfo=timezone.utc))
-    assert not certificate1.is_valid(when=datetime(2018, 4, 5, 12, 14, 14,
+    assert not certificate1.is_valid(when=datetime(2021, 4, 5, 12, 14, 14,
                                                    tzinfo=timezone.utc))
     assert not certificate1.is_valid(when=datetime(2013, 4, 2, 10, 11, 12,
                                                    tzinfo=timezone.utc))
@@ -121,7 +138,7 @@ def test_certificate_valid():
     assert certificate1_revoked.domain_name == '*.senza.example.com'
     assert not certificate1_revoked.is_valid(when=datetime(2016, 4, 5, 12, 14, 14,
                                                            tzinfo=timezone.utc))
-    assert not certificate1_revoked.is_valid(when=datetime(2018, 4, 5, 12, 14, 14,
+    assert not certificate1_revoked.is_valid(when=datetime(2021, 4, 5, 12, 14, 14,
                                                            tzinfo=timezone.utc))
     assert not certificate1_revoked.is_valid(when=datetime(2013, 4, 2, 10, 11, 12,
                                                            tzinfo=timezone.utc))
@@ -153,7 +170,7 @@ def test_certificate_get_by_arn(monkeypatch):
     assert certificate1.domain_name == '*.senza.example.com'
     assert certificate1.is_valid(when=datetime(2016, 4, 5, 12, 14, 14,
                                                tzinfo=timezone.utc))
-    assert not certificate1.is_valid(when=datetime(2018, 4, 5, 12, 14, 14,
+    assert not certificate1.is_valid(when=datetime(2021, 4, 5, 12, 14, 14,
                                                    tzinfo=timezone.utc))
     assert not certificate1.is_valid(when=datetime(2013, 4, 2, 10, 11, 12,
                                                    tzinfo=timezone.utc))
@@ -201,6 +218,12 @@ def test_get_certificates(monkeypatch):
     assert len(certificates_net) == 1
     assert certificates_net[0].arn == 'arn:aws:acm:eu-west-1:cert2'
 
+    m_client.describe_certificate.side_effect = [{'Certificate': CERT3}]
+    certificates_net = list(acm.get_certificates(valid_only=False,
+                                                 domain_name="registry.opensource.zalan.do"))
+    assert len(certificates_net) == 1
+    assert certificates_net[0].arn == 'arn:aws:acm:eu-west-1:cert3'
+
 
 def test_arn_is_acm_certificate():
     assert ACMCertificate.arn_is_acm_certificate('arn:aws:acm:certificate')

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
arrow==1.2.3
attrs==22.2.0
boto3==1.23.10
botocore==1.26.10
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
clickclick==20.10.2
coverage==6.2
dnspython==2.2.1
idna==3.10
importlib-metadata==4.8.3
iniconfig==1.1.1
jmespath==0.10.0
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pystache==0.6.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
PyYAML==6.0.1
raven==6.10.0
requests==2.27.1
s3transfer==0.5.2
six==1.17.0
stups-cli-support==1.1.22
stups-pierone==1.1.56
-e git+https://github.com/zalando-stups/senza.git@d5aa551914e024e9bf0bde97455db3a4eab62896#egg=stups_senza
stups-tokens==1.1.19
stups-zign==1.2
tomli==1.2.3
typing==3.7.4.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: senza
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - arrow==1.2.3
      - attrs==22.2.0
      - boto3==1.23.10
      - botocore==1.26.10
      - charset-normalizer==2.0.12
      - click==8.0.4
      - clickclick==20.10.2
      - coverage==6.2
      - dnspython==2.2.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jmespath==0.10.0
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pystache==0.6.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.1
      - raven==6.10.0
      - requests==2.27.1
      - s3transfer==0.5.2
      - six==1.17.0
      - stups-cli-support==1.1.22
      - stups-pierone==1.1.56
      - stups-tokens==1.1.19
      - stups-zign==1.2
      - tomli==1.2.3
      - typing==3.7.4.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/senza

tests/test_manaus/test_acm.py::test_get_certificates
tests/test_manaus/test_acm.py::test_certificate_valid tests/test_manaus/test_acm.py::test_certificate_comparison tests/test_manaus/test_acm.py::test_certificate_get_by_arn tests/test_manaus/test_acm.py::test_certificate_matches tests/test_manaus/test_acm.py::test_arn_is_acm_certificate
senza/manaus/acm.py
senza/manaus/acm.py