zalando-stups / senza

Deploy immutable application stacks and create and execute AWS CloudFormation templates in a sane way

Home Page:https://pypi.python.org/pypi/stups-senza

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Traffic update fails on a stack with parameters that use `AllowedPatterns`

imduffy15 opened this issue · comments

Hi All,

When executing

senza traffic stack version 100

It is expected that senza will go update the associated DNS weight of the record pointing at the ELB.
However, this fails. Our senza definition file has a few parameters that have AllowedPatterns specified, as a result when stack.update() is executed it fails.

As a workaround I've been commenting out https://github.com/zalando-stups/senza/blob/master/senza/traffic.py#L182 and the associated try catch which makes it work as expected.

Can you provide a minimal Senza definition YAML to reproduce the problem? I never used AllowedPatterns myself.

No problem at all @hjacobs

SenzaInfo:
  StackName: "example-{{Arguments.Stage}}"
  Parameters:
    - ApplicationId:
        Description: "example"
        Default: "example"
    - DockerSource:
        Description: "The Docker source"
        Default: "registry.opensource.zalan.do/team/example"
    - DockerTag:
        Description: "The Docker source tag"
    - MintBucket:
        Description: "The mint S3 bucket for OAuth 2.0 credentials"
        Default: "mint-{{AccountInfo.AccountID}}-{{AccountInfo.Region}}"
    - JdbcUsername:
        Description: "Database Username"
        Default: "admin"
        NoEcho: true
        AllowedPattern: "[a-zA-Z][a-zA-Z0-9_]*"
    - Stage:
        Description: "Deployment stage acceptance, performance test, uat, production etc."
        AllowedValues:
          - acceptance-test
          - performance-test
          - uat
          - prod
    - Environment:
        Description: "Defines if resources are part of a test run or production, used for filtering zmon alerts"
        AllowedValues:
          - test
          - prod

SenzaComponents:
  - Configuration:
      Type: Senza::StupsAutoConfiguration
  - AppServer:
      Type: Senza::TaupageAutoScalingGroup
      IamRoles: [{Ref: Roles}]
      ElasticLoadBalancer: AppLoadBalancer
      InstanceType: c4.xlarge
      AssociatePublicIpAddress: false
      SecurityGroups:
        - "Fn::GetAtt" : [ "AppSecurityGroup" , "GroupId" ]
      TaupageConfig:
        application_id: "{{Arguments.ApplicationId}}"
        application_version: "{{Arguments.DockerTag}}"
        runtime: Docker
        source: "{{Arguments.DockerSource}}:{{Arguments.DockerTag}}"
        ports:
          8080: 8080
        root: true
        health_check_path: /
        health_check_port: 8080
        mint_bucket: "{{Arguments.MintBucket}}"
  - AppLoadBalancer:
      Type: Senza::WeightedDnsElasticLoadBalancer
      HTTPPort: 8080
      MainDomain: "{{Arguments.ApplicationId}}-{{Arguments.Stage}}-{{AccountInfo.Region}}.{{AccountInfo.Domain}}"
      HealthCheckPath: /
      SecurityGroups:
        - "Fn::GetAtt" : [ "ELBSecurityGroup" , "GroupId" ]
      SSLCertificateId: "arn:aws:acm:{{AccountInfo.Region}}:{{AccountInfo.AccountID}}:certificate/eeeeeeee-aaaa-bbbb-cccc-ffffffffffff"
      Scheme: internal

Resources:
  Roles:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: MintAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: "s3:GetObject"
                Resource: ["arn:aws:s3:::{{Arguments.MintBucket}}/{{Arguments.ApplicationId}}/*"]
        - PolicyName: KMSAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: 
                  - "kms:Decrypt"
                  - "kms:Encrypt"
                Resource: 
                  - "arn:aws:kms:{{AccountInfo.Region}}:{{AccountInfo.AccountID}}:key/eeeeeeee-aaaa-bbbb-cccc-ffffffffffff"

  ELBSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: "Example ELB Security Group"
        SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: "0.0.0.0/0"

  AppSecurityGroup:
      Type: AWS::EC2::SecurityGroup
      Properties:
        GroupDescription: "Example Security Group"
        SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: "0.0.0.0/0"
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          CidrIp: "0.0.0.0/0"

Any updated on this @hjacobs we're working around it with the following patch:

--- traffic.py	2017-01-20 16:50:24.000000000 +0000
+++ traffic2.py	2017-01-20 16:57:50.000000000 +0000
@@ -170,22 +170,17 @@
             except NameError:
                 raise ELBNotFound(dns_name)
 
-            try:
-                stack.update()
-            except StackNotUpdated:
-                # make sure we update DNS records which were not updated via CloudFormation
-                record = None
-                for r in Route53.get_records(name=dns_name):
-                    if r.set_identifier == stack_name:
-                        record = r
-                        break
-                if record and record.weight != percentage:
-                    record.weight = percentage
-                    hosted_zone.upsert([record],
-                                       comment="Change weight of {} to {}".format(stack_name,
-                                                                                  percentage))
-                    changed = True
-            else:
+            # make sure we update DNS records which were not updated via CloudFormation
+            record = None
+            for r in Route53.get_records(name=dns_name):
+                if r.set_identifier == stack_name:
+                    record = r
+                    break
+            if record and record.weight != percentage:
+                record.weight = percentage
+                hosted_zone.upsert([record],
+                                   comment="Change weight of {} to {}".format(stack_name,
+                                                                              percentage))
                 changed = True
 
         if changed: