brabster / crucible

AWS CloudFormation templates built with Clojure
Eclipse Public License 1.0
72 stars 18 forks source link

Fn::GetAZs implementation #199

Open bizm opened 4 years ago

bizm commented 4 years ago

Not sure how to implement Fn::GetAZs function so that i can have something like

AvailabilityZone: !Select [ 0, !GetAZs '' ]

or

AvailabilityZone:
  Fn::Select:
  - '0'
  - {'Fn::GetAZs': ''}

Tried this one

(s/def ::get-azs (s/keys :req [::values/type ::region]))
(defmethod values/value-type ::get-azs [_] ::get-azs)
(defmethod values/encode-value ::get-azs [{:keys [::region]}]
  {"Fn::GetAZs" region})
(defn get-azs [region]
  {::values/type ::get-azs
   ::region region})

:subnet-a (ec2/subnet {
              ::ec2/availability-zone (select 0 (get-azs ""))
              ::ec2/vpc-id (xref :vpc)
              ::ec2/cidr-block (cidr-block 28)
              ::ec2/map-public-ip-on-launch "true"})

but getting this error

Invalid resource properties-- Spec failed --------------------

  {:crucible.aws.ec2/availability-zone {:crucible.values/type :crucible.values/select,
                                        :crucible.values/index 0,
                                        :crucible.values/fn-values
                                        {:crucible.values/type :infra.ecs/get-azs, :infra.ecs/region ""}},
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   :crucible.aws.ec2/vpc-id ...,
   :crucible.aws.ec2/cidr-block ...,
   :crucible.aws.ec2/map-public-ip-on-launch ...}

should satisfy

  string?

or value

  {:crucible.aws.ec2/availability-zone
   {:crucible.values/type ...,
    :crucible.values/index ...,
    :crucible.values/fn-values {:crucible.values/type :infra.ecs/get-azs, :infra.ecs/region ""}},
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   :crucible.aws.ec2/vpc-id ...,
   :crucible.aws.ec2/cidr-block ...,
   :crucible.aws.ec2/map-public-ip-on-launch ...}

should satisfy

  vector?

However it doesn't fail if i change subnet code to

:subnet-a (ec2/subnet {
              ::ec2/availability-zone (select 0 [(get-azs "")])
              ::ec2/vpc-id (xref :vpc)
              ::ec2/cidr-block (cidr-block 28)
              ::ec2/map-public-ip-on-launch "true"})

but in that case it produces code like

AvailabilityZone:
  Fn::Select:
  - '0'
  - - {'Fn::GetAZs': ''}

which is not correct.

bizm commented 4 years ago

For now made it work with this temporary fix:

(s/def ::get-azs (s/keys :req [::values/type ::index]))
(defmethod values/value-type ::get-azs [_] ::get-azs)
(defmethod values/encode-value ::get-azs [{:keys [::index]}]
  {"Fn::Select" [index {"Fn::GetAZs" ""}]})
(defn get-azs [index]
  {::values/type ::get-azs
   ::index index})

but obviously there should be some better way.

brabster commented 4 years ago

Hey there @bizm sorry I didn't see your issue. I'll give you a shout when I've had a proper look.