aws-cloudformation / cloudformation-resource-schema

The CloudFormation Resource Schema defines the shape and semantic for resources provisioned by CloudFormation. It is used by provider developers using the CloudFormation RPDK.
Apache License 2.0
90 stars 38 forks source link

How to identify resource attributes? #59

Closed fsenart closed 4 years ago

fsenart commented 4 years ago

Hi there,

When reading the schema of any resource, I cannot figure out how to identify the resource attributes.

Take for example AWS::Cloud9::EnvironmentEC2, the AWS CloudFormation doc states that Arn and Name can be retrieved via Fn::GetAtt, however in the corresponding JSON schema (see below), these two fields are specified in the properties of the specification but there is no additional information that tag them as being available as attributes via Fn::GetAtt.

Are we supposed to continue to use the AWS CloudFormation Resource Specification in addition to these new JSON schemas? Or you guys will update the schemas to add the missing pieces? Or I am totally wrong about how we are supposed to leverage these schemas?

{
  "typeName" : "AWS::Cloud9::EnvironmentEC2",
  "description" : "Resource Type definition for AWS::Cloud9::EnvironmentEC2",
  "additionalProperties" : false,
  "properties" : {
    "Arn" : {
      "type" : "string"
    },
    "Name" : {
      "type" : "string"
    },
    "Repositories" : {
      "type" : "array",
      "uniqueItems" : false,
      "items" : {
        "$ref" : "#/definitions/Repository"
      }
    },
    "OwnerArn" : {
      "type" : "string"
    },
    "Description" : {
      "type" : "string"
    },
    "AutomaticStopTimeMinutes" : {
      "type" : "integer"
    },
    "SubnetId" : {
      "type" : "string"
    },
    "EnvironmentId" : {
      "type" : "string"
    },
    "InstanceType" : {
      "type" : "string"
    }
  },
  "definitions" : {
    "Repository" : {
      "type" : "object",
      "additionalProperties" : false,
      "properties" : {
        "PathComponent" : {
          "type" : "string"
        },
        "RepositoryUrl" : {
          "type" : "string"
        }
      },
      "required" : [ "RepositoryUrl", "PathComponent" ]
    }
  },
  "required" : [ "InstanceType" ],
  "readOnlyProperties" : [ "/properties/Arn", "properties/EnvirontmentId" ],
  "createOnlyProperties" : [ "/properties/AutomaticStopTimeMinutes", "/properties/OwnerArn", "/properties/Name", "/properties/InstanceType", "/properties/SubnetId", "/properties/Repositories", "/properties/Description" ],
  "primaryIdentifier" : [ "properties/EnvirontmentId" ],
  "additionalIdentifiers" : [ "/properties/Arn" ]
}
rjlohan commented 4 years ago

Firstly, we will continue to support the existing Resource Specification for the time being. Over time though we expect to consolidate around these new schemas as they bring more information and context than was available in the Resource Specification.

Now to your specific questions, when used in a CloudFormation template, you can think of these things;

Does that help?

fsenart commented 4 years ago

Thank you very much for your quick answer.

When you say that

we expect to consolidate around these new schemas

Does that mean that both existing specs and new schemas are supported and the future will be new schemas centric? Indeed, the fact that GetAtt should support readOnlyProperties was my first guess, however, when trying to deploy the following template, it seems that EnvironmentId is not known as an attribute:

Resources:
  Foo:
    Type: AWS::Cloud9::EnvironmentEC2
    Properties:
      InstanceType: t2.micro

Outputs:
  Out:
    Value: !GetAtt Foo.EnvironmentId
[Error] /Outputs/Out/Value/Fn::GetAtt: Resource type AWS::Cloud9::EnvironmentEC2 does not support attribute {EnvironmentId}.

I saw this same error with other resources as well (for example AWS::IAM::Group has a read-only attribute Id that cannot be retrieved via GetAtt, etc.). Is it because the announcement has been made today and it will behave as you've described in the coming days or should we expect this behavior being supported eventually but not anytime soon?

rjlohan commented 4 years ago

You're right - there are a few issues with these generated schemas. As we start to migrate more resources to open source (e.g; AWS::Logs::LogGroup) we will be able to iron out some of these inconsistencies.

In this case the clarification I can add is that when a property appears in both the primaryIdentifier and readOnlyProperties then you should expect to !Ref the resource to get that value.

There is also some other nuance around the property appearing in the createOnlyProperties section which we need to iron out.

Essentially, what we are aiming to support at this time is the following; 1) primaryIdentifier can only be acquired through a !Ref 2) any property which appears in both readOnlyProperties and createOnlyProperties should be acquired via !GetAtt but even then there are inconsistencies (including this resource where the Name can be acquired by !GetAtt

Over time what we will actually move towards is the ability to !GetAtt any property, but we have some internal migrations to do first. It's a little tricky in the interim and I'd suggest relying on the CloudFormation Documentation as the source of truth on this for now.

fsenart commented 4 years ago

Thank you for all these explanations and your ongoing efforts to make CloudFormation more open. I will close the issue as my question has been answered, but I also count on you to keep the community informed as your support of these new schemas become more official :smiley:.