{"id":23530229,"url":"https://github.com/clburlison/terraform-munki","last_synced_at":"2025-04-22T17:24:54.495Z","repository":{"id":44755019,"uuid":"136534825","full_name":"clburlison/terraform-munki","owner":"clburlison","description":"Terraform module for building munki resources in AWS. ","archived":false,"fork":false,"pushed_at":"2024-08-13T19:11:03.000Z","size":403,"stargazers_count":31,"open_issues_count":0,"forks_count":5,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-22T17:24:42.434Z","etag":null,"topics":["aws","munki","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clburlison.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-07T21:49:56.000Z","updated_at":"2024-08-13T19:09:47.000Z","dependencies_parsed_at":"2024-08-09T22:23:29.863Z","dependency_job_id":"7832c741-7578-46ca-8b90-5ebf54775798","html_url":"https://github.com/clburlison/terraform-munki","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clburlison%2Fterraform-munki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clburlison%2Fterraform-munki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clburlison%2Fterraform-munki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clburlison%2Fterraform-munki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clburlison","download_url":"https://codeload.github.com/clburlison/terraform-munki/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250285988,"owners_count":21405346,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","munki","terraform"],"created_at":"2024-12-25T21:16:21.150Z","updated_at":"2025-04-22T17:24:54.466Z","avatar_url":"https://github.com/clburlison.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-munki module\n\nThis terraform module creates all the necessary resources in AWS for highly\nscalable munki web setup using AWS S3 for object storage and AWS CloudFront\n(CDN) for content distribution. You can optionally secure the CDN via signed\nURLs so only clients that have your signing certificate can download content.\n\n## Table of Contents\n\n* [**High Level Features**](#high-level-features)\n* [**Versions**](#versions)\n* [**Terraform Usage**](#terraform-usage)\n* [**CloudFront signing key**](#cloudfrount-signing-key)\n* [**SNS Alerts**](#sns-alerts)\n* [**Lambda Notes**](#lambda-notes)\n* [**Inputs**](#inputs)\n* [**Outputs**](#outputs)\n\n## NOTE\n\nCurrently server side `makecatalogs` via the [s3 Repo Plugin](https://github.com/clburlison/Munki-s3Repo-Plugin) does not function with python3 and munki version 4+. I recommend you keep `server_side_makecatalogs` set to `false`.\n\n## High Level Features\n\n* Restrictions on the S3 bucket to disallow any direct connections\n* Use a custom DNS name for the web server or use a supplied URL from AWS\n* ~~Rebuild the catalog files whenever a pkginfo file or icon is updated or modified~~ See Note above\n* Only pay for what you use\n* Optional SNS Alert when a warning or error happen during `makecatalog` run\n* Custom TTL values for assets\n* Baisc Auth and Cert Based ACL controls\n\n## Versions\n\nAt this time, it is impossible to supply your own lambda payload as such you\nare stuck on the following versions.\n\n* Munki - [v3.2.1]\n* Munki s3Repo Plugin - [0.4.4](https://github.com/clburlison/Munki-s3Repo-Plugin)\n\n## Terraform Usage\n\n```hcl\nmodule \"munki-service\" {\n  source = \"git@github.com:clburlison/terraform-munki.git?ref=v1.1.0\"\n  s3_bucket_name = \"megacorp-munki-repo\"\n\n  tags = {\n    Environment  = \"prod\"\n    BusinessUnit = \"ClientABC\"\n  }\n}\n\nFor additional instructions please checkout the [examples](./examples) directory.\n```\n\n## CloudFront signing key\n\nThe CloudFront signing key can not be automatically created. This key can also\nonly be created by the root account owner, administrator IAM users will not\nwork.\n\nThe creation process can be followed in the following Amazon doc:\n\n[To create CloudFront key pairs]\n\nor via the following graphic:\n\n![CF Key Creation](pics/cf_key_creation.png)\n\n## SNS Alerts\n\nTerraform is unable to create and validate Simple Notification Service (SNS)\nresources so a topic and subscription must be created manually. The following\nsteps will guide you through an email alert:\n\n1. Log into the AWS Console\n1. Go to the Simple Notification Service (SNS) service\n1. Create a new topic\n1. Click on the created topic ARN to go to the details page\n1. Create a subscription\n1. Select the protocol and options you want\n1. Confirm the subscription (required for the email protocol)\n1. Copy the Topic ARN from this page and use in the terraform `alarm_arn` variable\n\n## Lambda Notes\n\nThe `lambda_makecatalogs.py` file runs as a AWS Lambda function. It is\ntriggered from the following s3 events:\n\n* a file under pkginfo/ is modified or uploaded\n* a file under icons/ with the extensions of the `.png` or `.jpg` is modified or uploaded\n\nIf this setup is destroyed and recreated the 'munki-s3-rw' policy will need to be re-applied to the 'munki_s3' user.\n\n\u003c!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 0.12 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_archive\"\u003e\u003c/a\u003e [archive](#provider\\_archive) | 2.2.0 |\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | 5.0 |\n\n## Modules\n\nNo modules.\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [aws_cloudfront_distribution.munki](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |\n| [aws_cloudfront_distribution.munki_basic_auth](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |\n| [aws_cloudfront_origin_access_identity.cf-identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_identity) | resource |\n| [aws_cloudwatch_log_group.munki_makecatalogs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |\n| [aws_cloudwatch_log_metric_filter.errors](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_metric_filter) | resource |\n| [aws_cloudwatch_log_metric_filter.warnings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_metric_filter) | resource |\n| [aws_cloudwatch_metric_alarm.Makecatalogs-Error](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |\n| [aws_cloudwatch_metric_alarm.Makecatalogs-Warning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |\n| [aws_iam_policy.munki-s3-rw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |\n| [aws_iam_role.lambda_execution_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |\n| [aws_iam_role.makecatalogs_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |\n| [aws_iam_role_policy.lambda_execution_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |\n| [aws_iam_role_policy_attachment.lambda_iam_policy_basic_execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |\n| [aws_iam_role_policy_attachment.lambda_munki_s3_rw_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |\n| [aws_lambda_alias.alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_alias) | resource |\n| [aws_lambda_function.basic_auth_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |\n| [aws_lambda_function.lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |\n| [aws_lambda_permission.allow_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |\n| [aws_lambda_permission.allow_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |\n| [aws_s3_bucket.munki-bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |\n| [aws_s3_bucket_acl.munki-bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource |\n| [aws_s3_bucket_notification.bucket_notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_notification) | resource |\n| [aws_s3_bucket_policy.munki-bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |\n| [aws_s3_bucket_server_side_encryption_configuration.munki-bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |\n| [archive_file.basic_auth_payload](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |\n| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |\n| [aws_iam_policy_document.lambda_execution_role_assume_role_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.lambda_execution_role_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.munki_s3_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_alarm_arn\"\u003e\u003c/a\u003e [alarm\\_arn](#input\\_alarm\\_arn) | The arn to send alerts to on lambda errors and warnings | `string` | `\"\"` | no |\n| \u003ca name=\"input_basic_auth_password\"\u003e\u003c/a\u003e [basic\\_auth\\_password](#input\\_basic\\_auth\\_password) | Password for munki basic auth | `string` | `\"\"` | no |\n| \u003ca name=\"input_basic_auth_user\"\u003e\u003c/a\u003e [basic\\_auth\\_user](#input\\_basic\\_auth\\_user) | Username for munki basic auth | `string` | `\"\"` | no |\n| \u003ca name=\"input_catalogs_ordered_cache_behavior_default_ttl\"\u003e\u003c/a\u003e [catalogs\\_ordered\\_cache\\_behavior\\_default\\_ttl](#input\\_catalogs\\_ordered\\_cache\\_behavior\\_default\\_ttl) | The default amount of time (in seconds) that a catalog object is in a CloudFront cache before CloudFront forwards another request in the absence of an Cache-Control max-age or Expires header. | `number` | `30` | no |\n| \u003ca name=\"input_catalogs_ordered_cache_behavior_max_ttl\"\u003e\u003c/a\u003e [catalogs\\_ordered\\_cache\\_behavior\\_max\\_ttl](#input\\_catalogs\\_ordered\\_cache\\_behavior\\_max\\_ttl) | The maximum amount of time (in seconds) that a catalog object is in a CloudFront cache before CloudFront forwards another request to your origin to determine whether the object has been updated. | `number` | `60` | no |\n| \u003ca name=\"input_catalogs_ordered_cache_behavior_min_ttl\"\u003e\u003c/a\u003e [catalogs\\_ordered\\_cache\\_behavior\\_min\\_ttl](#input\\_catalogs\\_ordered\\_cache\\_behavior\\_min\\_ttl) | The minimum amount of time (in seconds) that you want catalog objects to stay in CloudFront caches before CloudFront queries your origin to see whether the object has been updated. | `number` | `0` | no |\n| \u003ca name=\"input_cf_default_certificate\"\u003e\u003c/a\u003e [cf\\_default\\_certificate](#input\\_cf\\_default\\_certificate) | true if you want viewers to use HTTPS to request your objects and you're using the CloudFront domain name for your distribution. Specify this, cf\\_acm\\_certificate\\_arn, or cf\\_iam\\_certificate\\_id | `string` | `\"true\"` | no |\n| \u003ca name=\"input_cf_dns_aliases\"\u003e\u003c/a\u003e [cf\\_dns\\_aliases](#input\\_cf\\_dns\\_aliases) | Optionally a list of dns aliases to assign to the CloudFront distribution point | `list(string)` | `[]` | no |\n| \u003ca name=\"input_cf_minimum_protocol_version\"\u003e\u003c/a\u003e [cf\\_minimum\\_protocol\\_version](#input\\_cf\\_minimum\\_protocol\\_version) | The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. One of SSLv3, TLSv1, TLSv1\\_2016, TLSv1.1\\_2016 or TLSv1.2\\_2018 | `string` | `\"TLSv1.2_2018\"` | no |\n| \u003ca name=\"input_cf_price_class\"\u003e\u003c/a\u003e [cf\\_price\\_class](#input\\_cf\\_price\\_class) | The CloudFront pricing tier. One of PriceClass\\_All, PriceClass\\_200, PriceClass\\_100 | `string` | `\"PriceClass_All\"` | no |\n| \u003ca name=\"input_cf_ssl_cert_arn\"\u003e\u003c/a\u003e [cf\\_ssl\\_cert\\_arn](#input\\_cf\\_ssl\\_cert\\_arn) | The ARN of the AWS Certificate Manager certificate to use. Specify this, cf\\_cloudfront\\_default\\_certificate, or cf\\_iam\\_certificate\\_id. The ACM certificate must be in US-EAST-1 | `string` | `\"\"` | no |\n| \u003ca name=\"input_cf_ssl_support_method\"\u003e\u003c/a\u003e [cf\\_ssl\\_support\\_method](#input\\_cf\\_ssl\\_support\\_method) | Specifies how you want CloudFront to serve HTTPS requests. Required if you specify acm\\_certificate\\_arn. One of vip or sni-only. vip is $600 a month don't select that option! | `string` | `\"\"` | no |\n| \u003ca name=\"input_cf_trusted_signers\"\u003e\u003c/a\u003e [cf\\_trusted\\_signers](#input\\_cf\\_trusted\\_signers) | The AWS accounts, if any, that you want to allow to create signed URLs for private content. Use ['self'] if you want to target the account that owns this CloudFront distribution point | `list(string)` | `[]` | no |\n| \u003ca name=\"input_default_cache_behavior_default_ttl\"\u003e\u003c/a\u003e [default\\_cache\\_behavior\\_default\\_ttl](#input\\_default\\_cache\\_behavior\\_default\\_ttl) | The default amount of time (in seconds) that an object is in a CloudFront cache before CloudFront forwards another request in the absence of an Cache-Control max-age or Expires header. | `number` | `86400` | no |\n| \u003ca name=\"input_default_cache_behavior_max_ttl\"\u003e\u003c/a\u003e [default\\_cache\\_behavior\\_max\\_ttl](#input\\_default\\_cache\\_behavior\\_max\\_ttl) | The maximum amount of time (in seconds) that an object is in a CloudFront cache before CloudFront forwards another request to your origin to determine whether the object has been updated. | `number` | `31536000` | no |\n| \u003ca name=\"input_default_cache_behavior_min_ttl\"\u003e\u003c/a\u003e [default\\_cache\\_behavior\\_min\\_ttl](#input\\_default\\_cache\\_behavior\\_min\\_ttl) | The minimum amount of time (in seconds) that you want objects to stay in CloudFront caches before CloudFront queries your origin to see whether the object has been updated. | `number` | `0` | no |\n| \u003ca name=\"input_enable_icons_basic_auth\"\u003e\u003c/a\u003e [enable\\_icons\\_basic\\_auth](#input\\_enable\\_icons\\_basic\\_auth) | When set to 'true' the resource will enable basic auth for icons/ subpath | `bool` | `true` | no |\n| \u003ca name=\"input_icons_ordered_cache_behavior_default_ttl\"\u003e\u003c/a\u003e [icons\\_ordered\\_cache\\_behavior\\_default\\_ttl](#input\\_icons\\_ordered\\_cache\\_behavior\\_default\\_ttl) | The default amount of time (in seconds) that a icon object is in a CloudFront cache before CloudFront forwards another request in the absence of an Cache-Control max-age or Expires header. | `number` | `30` | no |\n| \u003ca name=\"input_icons_ordered_cache_behavior_max_ttl\"\u003e\u003c/a\u003e [icons\\_ordered\\_cache\\_behavior\\_max\\_ttl](#input\\_icons\\_ordered\\_cache\\_behavior\\_max\\_ttl) | The maximum amount of time (in seconds) that a icon object is in a CloudFront cache before CloudFront forwards another request to your origin to determine whether the object has been updated. | `number` | `60` | no |\n| \u003ca name=\"input_icons_ordered_cache_behavior_min_ttl\"\u003e\u003c/a\u003e [icons\\_ordered\\_cache\\_behavior\\_min\\_ttl](#input\\_icons\\_ordered\\_cache\\_behavior\\_min\\_ttl) | The minimum amount of time (in seconds) that you want icon objects to stay in CloudFront caches before CloudFront queries your origin to see whether the object has been updated. | `number` | `0` | no |\n| \u003ca name=\"input_manifests_ordered_cache_behavior_default_ttl\"\u003e\u003c/a\u003e [manifests\\_ordered\\_cache\\_behavior\\_default\\_ttl](#input\\_manifests\\_ordered\\_cache\\_behavior\\_default\\_ttl) | The default amount of time (in seconds) that a manifest object is in a CloudFront cache before CloudFront forwards another request in the absence of an Cache-Control max-age or Expires header. | `number` | `30` | no |\n| \u003ca name=\"input_manifests_ordered_cache_behavior_max_ttl\"\u003e\u003c/a\u003e [manifests\\_ordered\\_cache\\_behavior\\_max\\_ttl](#input\\_manifests\\_ordered\\_cache\\_behavior\\_max\\_ttl) | The maximum amount of time (in seconds) that a manifest object is in a CloudFront cache before CloudFront forwards another request to your origin to determine whether the object has been updated. | `number` | `60` | no |\n| \u003ca name=\"input_manifests_ordered_cache_behavior_min_ttl\"\u003e\u003c/a\u003e [manifests\\_ordered\\_cache\\_behavior\\_min\\_ttl](#input\\_manifests\\_ordered\\_cache\\_behavior\\_min\\_ttl) | The minimum amount of time (in seconds) that you want manifest objects to stay in CloudFront caches before CloudFront queries your origin to see whether the object has been updated. | `number` | `0` | no |\n| \u003ca name=\"input_name\"\u003e\u003c/a\u003e [name](#input\\_name) | Name to be used on all resources as the identifier | `string` | `\"munki\"` | no |\n| \u003ca name=\"input_s3_bucket_create\"\u003e\u003c/a\u003e [s3\\_bucket\\_create](#input\\_s3\\_bucket\\_create) | Set to true to create a new s3 bucket. If false you can reuse a current bucket | `bool` | `true` | no |\n| \u003ca name=\"input_s3_bucket_name\"\u003e\u003c/a\u003e [s3\\_bucket\\_name](#input\\_s3\\_bucket\\_name) | The s3 bucket name to use | `any` | n/a | yes |\n| \u003ca name=\"input_s3_encryption_enabled\"\u003e\u003c/a\u003e [s3\\_encryption\\_enabled](#input\\_s3\\_encryption\\_enabled) | When set to 'true' the resource will have aes256 encryption enabled by default | `bool` | `true` | no |\n| \u003ca name=\"input_server_side_makecatalogs\"\u003e\u003c/a\u003e [server\\_side\\_makecatalogs](#input\\_server\\_side\\_makecatalogs) | Set to true to enable server side makecatalogs when s3 bucket changes happen | `bool` | `false` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_cf_domain_name\"\u003e\u003c/a\u003e [cf\\_domain\\_name](#output\\_cf\\_domain\\_name) | The cloudfront distribution point domain name |\n| \u003ca name=\"output_cf_hosted_zone_id\"\u003e\u003c/a\u003e [cf\\_hosted\\_zone\\_id](#output\\_cf\\_hosted\\_zone\\_id) | The cloudfront distribution point zone id |\n\u003c!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --\u003e\n\n\n\u003c!-- html urls --\u003e\n\n[To create CloudFront key pairs]: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-creating-cloudfront-key-pairs\n[v3.2.1]: https://github.com/munki/munki/releases/tag/v3.2.1\n[CHANGELOG.md]: ./CHANGELOG.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclburlison%2Fterraform-munki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclburlison%2Fterraform-munki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclburlison%2Fterraform-munki/lists"}