Skip to content

Commit

Permalink
bump cloudformation version: 65 -> 153 (#17)
Browse files Browse the repository at this point in the history
- [x] migrate dev env to haskell.nix
- [x] cloudformation v65 -> v153
- [x] sam latest
- [x] stop building full binary(too large...) should be able to filter
by nix args
  • Loading branch information
jcouyang authored Jan 26, 2024
2 parents e39e050 + f40ea21 commit e38ece7
Show file tree
Hide file tree
Showing 4,599 changed files with 47,364 additions and 1,461 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use nix
54 changes: 33 additions & 21 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,44 @@ jobs:
- uses: actions/checkout@v2
- name: Setup Dhall
uses: dhall-lang/setup-dhall@v4
- uses: cachix/install-nix-action@v12
with:
nix_path: nixpkgs=channel:nixos-21.05
version: '1.42.0'
- uses: cachix/install-nix-action@v20
with:
nix_path: nixpkgs=channel:nixos-23.05
extra_nix_config: |
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
substituters = https://cache.iog.io https://cache.nixos.org/
- uses: cachix/cachix-action@v12
with:
name: jcouyang
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Dhall test
run: |
dhall-to-json <<< "./examples/dynamo.dhall"
- name: build
run: nix-build
dhall-to-yaml <<< "./examples/dynamo.dhall"
nix-build ./examples/example0.nix --no-out-link
- name: Haskell test
run: nix-build ./nix/haskell.nix -A dhall-aws-cloudformation.components.tests.dhall-aws-cloudformation-test --no-out-link
docs:
runs-on: ubuntu-latest
if: "github.ref == 'refs/heads/master'"
needs:
- test
steps:
- uses: actions/checkout@v2
- name: Setup Dhall
uses: dhall-lang/setup-dhall@v4
- uses: cachix/install-nix-action@v20
with:
nix_path: nixpkgs=channel:nixos-23.05

- name: Checkout Docs
uses: actions/checkout@v2
with:
ref: gh-pages
path: gh-pages
- name: build
run: |
curl -L https://github.com/dhall-lang/dhall-haskell/releases/download/1.40.1/dhall-docs-1.0.7-x86_64-linux.tar.bz2 | tar --extract --bzip2
VERSION=$(dhall text < ./version.dhall)
./bin/dhall-docs --input ./ --base-import-url https://raw.githubusercontent.com/jcouyang/dhall-aws-cloudformation/${VERSION}
VERSION=$(nix-shell -p dhall --run 'dhall text < ./version.dhall')
nix-shell -p dhall-docs --run "dhall-docs --input . --base-import-url 'https://raw.githubusercontent.com/jcouyang/dhall-aws-cloudformation/'"$VERSION" --package-name dhall-aws-cloudformation --version $VERSION"
cp -r docs/* gh-pages/
cd gh-pages
git config user.name github-actions
Expand All @@ -57,11 +68,16 @@ jobs:
contents: write
steps:
- uses: actions/checkout@v2
- name: Setup Dhall
uses: dhall-lang/setup-dhall@v4
- uses: cachix/install-nix-action@v12
- uses: cachix/install-nix-action@v20
with:
nix_path: nixpkgs=channel:nixos-21.05
nix_path: nixpkgs=channel:nixos-23.05
extra_nix_config: |
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
substituters = https://cache.iog.io https://cache.nixos.org/
- uses: cachix/cachix-action@v12
with:
name: jcouyang
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Log in to the Container registry
uses: docker/login-action@v1.10.0
with:
Expand All @@ -70,15 +86,11 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: publish docker image
run: |
$(nix-build docker.nix) | docker load
LOCAL_VERSION=$(dhall text < ./version.dhall)
$(nix-build ./nix/docker.nix) | docker load
LOCAL_VERSION=$(nix-shell -p dhall --run 'dhall text < ./version.dhall')
docker tag ghcr.io/jcouyang/dhall-aws-cloudformation:latest ghcr.io/jcouyang/dhall-aws-cloudformation:$LOCAL_VERSION
docker push ghcr.io/jcouyang/dhall-aws-cloudformation:latest
docker push ghcr.io/jcouyang/dhall-aws-cloudformation:$LOCAL_VERSION
- name: package cache
run: |
nix-build package.nix
tar -czhf cache.tar.gz ./result
- name: tag release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -87,7 +99,7 @@ jobs:
LOCAL_VERSION=$(dhall text < ./version.dhall)
echo "main version is $LAST_RELEASE and current version is $LOCAL_VERSION"
if [ ${LAST_RELEASE:-0} != $LOCAL_VERSION ];then
hub release create -m "${LOCAL_VERSION}" -a ./cache.tar.gz "${LOCAL_VERSION}"
hub release create -m "${LOCAL_VERSION}" "${LOCAL_VERSION}"
fi
- name: publish doc
env:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ cabal.project.local~

# End of https://www.toptal.com/developers/gitignore/api/haskell
.idea
examples/readme.gen.*
examples/readme.gen.*
result
113 changes: 85 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@

`dhall-aws-cloudformation` contains [Dhall](https://github.com/dhall-lang/dhall-lang) bindings to AWS CloudFormation, so you can generate CloudFormation template from Dhall expressions. This will let you easily typecheck, template and modularize your CloudFormation definitions.

## :mag: [References](https://oyanglul.us/dhall-aws-cloudformation/package.dhall.html)
## :bulb: [Examples](https://oyanglul.us/dhall-aws-cloudformation/examples/index.html)
## :mag: [References](https://gh.1punch.dev/dhall-aws-cloudformation/package.dhall.html)
## :bulb: [Examples](https://gh.1punch.dev/dhall-aws-cloudformation/examples/index.html)

## :book: Usage

### Use resource schema
AWS Cloudformation has massive amount of specifications, to load all `package.dhall` remotely will be very slow

It is recommended to just import the only resources you need

> optionaly, if you really need all resources in `package.dhall`, [load the binary cache to local first](https://oyanglul.us/dhall-aws-cloudformation/package.dhall.html#load-packagedhall-binary-to-local-cache)
AWS Cloudformation has massive amount of specifications, to load all
dhall remotely will be very slow and impractical.

One simply way to make import faster is by only importing just each resource you need
#### Remote import resource
```dhall
let Function =
-- import Lambda Function type definition
https://github.com/jcouyang/dhall-aws-cloudformation/raw/0.9.69/cloudformation/AWS::Lambda::Function.dhall
https://raw.githubusercontent.com/jcouyang/dhall-aws-cloudformation/0.9.69/cloudformation/AWS::Lambda::Function.dhall
sha256:60937fd655917883d994e8593155453b823258e801792b0878b828b372946836

let Fn =
-- Intrinsic functions
https://github.com/jcouyang/dhall-aws-cloudformation/raw/0.9.69/Fn.dhall
https://raw.githubusercontent.com/jcouyang/dhall-aws-cloudformation/0.9.69/Fn.dhall
sha256:b2cf7212998902c44ba1bf1670a8e0bc40562542b9b525587cd044f317644e47

let S =
Expand Down Expand Up @@ -54,8 +53,8 @@ let example0 =
}

in example0
```

```
to convert to CloudFormation JSON file just
```
dhall-to-json < ./template.dhall > ./template.json
Expand Down Expand Up @@ -86,9 +85,70 @@ generates
}
}
}

```

### Intrinsic Function
Other way around is build the binary of subset of the resources using nix
#### Build and load package.dhall binary to local cache
Have something like `./examples/example0.nix`, and the dhall file you want to compile `./examples/example0.dhall`
```nix
let aws =
missing
sha256:a04e4db67b092e40987639cca5cd845f452b3984ee7ec77172f815a31e830325
let Function = aws.Cloudformation.`AWS::Lambda::Function`
let Fn = aws.Fn
let S =
{-
Each AWS String field can be either a String or a Intrinsic function, we can use `Fn.renderText "abc"` to create static string
Or `Fn.render (Ref "abc")` to create a function that ref to a string
-} Fn.renderText
let render =
-- function can be nested `render (Fn.Ref (Fn.GetAtt (Fn.String "abc.property")))`
Fn.render
let example0 =
{ Resources.HelloWorldFunction
= Function.Resources::{
, Properties = Function.Properties::{
, Handler = Some (S "index.handler")
, Code = Function.Code::{
, S3Bucket = Some (S "lambda-functions")
, S3Key = Some (S "amilookup.zip")
}
, Runtime = Some (S "nodejs12.x")
, Role = render (Fn.Ref "role logical id")
, Timeout = Some +25
, TracingConfig = Some { Mode = Some (S "Active") }
}
}
}
in example0
```
Add all the resources you need to `cf-preset`, run nix-build, if the subset is not too large it will be very quick, and you will see something like:
```
⚠ ─ If error occured, you may need to update the sha256 in your dhall file e.g.
│ let aws = missing sha256:a04e4db67b092e40987639cca5cd845f452b3984ee7ec77172f815a31e830325
```

Actually the first time it will fail since you can't guess the correct sha of the subset binary, now if you update example0.dhall with the correct sha,
it should then be able to compile to `./result/example0.yaml`
```dhall
let aws =
missing
sha256:a04e4db67b092e40987639cca5cd845f452b3984ee7ec77172f815a31e830325

let Function = aws.Cloudformation.`AWS::Lambda::Function`
```


### Intrinsic Function

The following intrinsic functions are implemented, you can find examples of using intrinsic function in [Fn.dhall document](https://oyanglul.us/dhall-aws-cloudformation/Fn.dhall.html)
- [x] Fn::Base64
Expand Down Expand Up @@ -116,10 +176,9 @@ So the compiler can just help you find the correct attributes available.

### Sam Policy Templates
Cloudformation's Policy document is loosy type as just JSON, it is hard to get the policy right and too many boilerplates to create a Dhall JSON data
thanks to [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html) there are some common policy documents we can laverage

Thanks to [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html) there are some common policy documents we can laverage

All these templates are translated into Dhall functions, so you don't need to use SAM to be able to use these policy documents.
these templates are translated into Dhall functions, so you don't need to use SAM to be able to use these policy documents.

```dhall
let Policy = https://github.com/jcouyang/dhall-aws-cloudformation/raw/0.9.69/cloudformation/AWS::IAM::Role/Policy.dhall
Expand All @@ -131,9 +190,7 @@ let Sam/Policy = https://github.com/jcouyang/dhall-aws-cloudformation/raw/0.9.69
}]
...
```

will generates

```json
{
"Policies": [
Expand Down Expand Up @@ -180,33 +237,32 @@ will generates

```
> nix-shell
$ stack build
$ stack test
$ cabal build
$ cabal test
```
### Generate Type Definitions

Type definitions are generated from config file `./config.dhall` which contains specifications used by [AWS CDK](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cfnspec/build-tools/update.sh) as well:
e definitions are generated from config file `./config.dhall` which contains specifications used by [AWS CDK](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/cfnspec/build-tools/update.sh) as well:
- [cloudformation](https://d1uauaxba7bl26.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json)
- [sam](https://raw.githubusercontent.com/awslabs/goformation/master/generate/sam-2016-10-31.json)


To regenerate types definition files, simply run
regenerate types definition files, simply run
```
$ stack run
$ cabal run
```

Or if you just want to regenerate dhall files without setting up haskell dev environment, just
if you just want to regenerate dhall files without setting up haskell dev environment, just
```sh
docker run --rm -v $(pwd):/data -w /data ghcr.io/jcouyang/dhall-aws-cloudformation
```

## :warning: Known Issue
:warning: Known Issue
The following CloudFormation definitions will raise assertion error due to invalid type definition such as empty type or cyclic import

- `AWS::EMR::Cluster`
- `AWS::EMR::InstanceGroupConfig`
- `AWS::EMR::InstanceFleetConfig`
- `AWS::Macie::FindingsFilter`
- `AWS::Connect::EvaluationForm`
- `AWS::IoTTwinMaker::ComponentType`
- `AWS::IoTTwinMaker::Entity`
- `AWS::Lex::Bot`
- `AWS::DataBrew::Recipe`
- `AWS::FIS::ExperimentTemplate`
- `AWS::SageMaker::ModelBiasJobDefinition`
Expand All @@ -223,4 +279,5 @@ The following CloudFormation definitions will raise assertion error due to inval
- `AWS::ServiceDiscovery::PublicDnsNamespace`
- `AWS::AmplifyUIBuilder::Component`
- `AWS::AmplifyUIBuilder::Theme`
- `AWS::EMRServerless::Application`

Loading

0 comments on commit e38ece7

Please sign in to comment.