{"id":19804173,"url":"https://github.com/victorock/ansible-operator-tower-config","last_synced_at":"2025-05-01T06:31:01.239Z","repository":{"id":90320713,"uuid":"317928475","full_name":"victorock/ansible-operator-tower-config","owner":"victorock","description":"Operator to Configure Tower based on Kubernetes extended CRDs.","archived":false,"fork":false,"pushed_at":"2020-12-02T23:57:46.000Z","size":62,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-06T10:07:38.234Z","etag":null,"topics":["ansible","ansible-operators","ansible-tower","awx","awx-ansible","kubernetes-operator","openshift-operator"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/victorock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2020-12-02T16:49:19.000Z","updated_at":"2025-04-04T01:42:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"ed026ff8-31cc-451f-9596-48234edfef98","html_url":"https://github.com/victorock/ansible-operator-tower-config","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorock%2Fansible-operator-tower-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorock%2Fansible-operator-tower-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorock%2Fansible-operator-tower-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorock%2Fansible-operator-tower-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/victorock","download_url":"https://codeload.github.com/victorock/ansible-operator-tower-config/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251835456,"owners_count":21651661,"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":["ansible","ansible-operators","ansible-tower","awx","awx-ansible","kubernetes-operator","openshift-operator"],"created_at":"2024-11-12T08:41:42.011Z","updated_at":"2025-05-01T06:31:01.232Z","avatar_url":"https://github.com/victorock.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"Kubernetes Operator for Tower Config\n=========\n\nSimple [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) to Configure Ansible Tower by Red Hat.  \nThis Operator is build using the [operator framework](https://operatorframework.io/), and will ensure the configuration of Ansible Tower and AWX based on Custom Resources Definitions describing the desired configurations.\n\n# Dependencies\n------------\n\nAll CRDs within this operator depend on a _Secret_ being defined within the desired namespace and this secret name must be given along with any of the CRs that wish, the _Secret_ itself has a particular k/v format:\n\n```YAML\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: toweraccess\n  namespace: myproject\n  type: Opaque\nstringData:\n  token: XXXXX\n  host: https://tower.victorock.io\n  verify_ssl: false\n```\n\n## [Building and Push](https://sdk.operatorframework.io/docs/building-operators/ansible/quickstart/#build-and-push-the-operator-image)\n---------\n\nUse the built-in Makefile targets to build and push your operator. Make sure to define IMG when you call make:\n\n```\nmake docker-build docker-push IMG=\u003csome-registry\u003e/\u003cproject-name\u003e:\u003ctag\u003e\n```\n\n\u003e NOTE: To allow the cluster pull the image the repository needs to be set as public or you must configure an image pull secret.\n\n\n## [Install and Run](https://sdk.operatorframework.io/docs/building-operators/ansible/quickstart/#run-the-operator)\n--------------------\n\nInstall the CRD and deploy the project to the cluster. Set IMG with make deploy to use the image you just pushed:\n\n```\nmake install\nmake deploy IMG=\u003csome-registry\u003e/\u003cproject-name\u003e:\u003ctag\u003e\n```\n\n## [Create](https://sdk.operatorframework.io/docs/building-operators/ansible/quickstart/#create-a-sample-custom-resource)\n----------\n\nCreate a sample CR:\n\n```\nkubectl apply -f config/samples/tower_v1alpha1_organization.yaml\n```\n\n\n# Documentation\n--------------\n\nThe following CRDs are implemented:\n\n| Custom Resource Definition | Implementation | Custom Resource Samples |\n|-------------------|--------------------|----------------------------------|\n[Credentials](config/crd/bases/tower.ansible.com_credentials.yaml) | [credential](roles/credential/defaults/main.yml) | [Credential](config/samples/tower_v1alpha1_credential.yaml) |  \n[CredentialInputSources](config/crd/bases/tower.ansible.com_credentialinputsources.yaml) | [credentialinputsource](roles/credentialinputsource/defaults/main.yml) | [CredentialInputSource](config/samples/tower_v1alpha1_credentialinputsource.yaml)\n[CredentialTypes](config/crd/bases/tower.ansible.com_credentialtypes.yaml) | [credentialtype](roles/credentialtype/defaults/main.yml) | [CredentialType](config/samples/tower_v1alpha1_credentialtype.yaml) |\n[Groups](config/crd/bases/tower.ansible.com_groups.yaml) | [group](roles/group/defaults/main.yml) | [Group](config/samples/tower_v1alpha1_group.yaml) |\n[Inventories](config/crd/bases/tower.ansible.com_inventories.yaml) | [inventory](roles/inventory/defaults/main.yml) | [Inventory](config/samples/tower_v1alpha1_inventory.yaml) |\n[InventorySources](config/crd/bases/tower.ansible.com_inventorysources.yaml) | [inventorysource](roles/inventorysource/defaults/main.yml) | [InventorySource](config/samples/tower_v1alpha1_inventorysource.yaml) |\n[JobTemplates](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [jobtemplate](roles/jobtemplate/defaults/main.yml) | [JobTemplate](config/samples/tower_v1alpha1_jobtemplate.yaml) |\n[Modules](config/crd/bases/tower.ansible.com_modules.yaml) | [module](roles/module/defaults/main.yml) | [Module](config/samples/tower_v1alpha1_module.yaml) |\n[Organizations](config/crd/bases/tower.ansible.com_organizations.yaml) | [organization](roles/organization/defaults/main.yml) | [Organization](config/samples/tower_v1alpha1_organization.yaml) |\n[Projects](config/crd/bases/tower.ansible.com_projects.yaml) | [project](roles/project/defaults/main.yml) | [Project](config/samples/tower_v1alpha1_project.yaml) |\n[Roles](config/crd/bases/tower.ansible.com_roles.yaml) | [role](roles/role/defaults/main.yml) | [Role](config/samples/tower_v1alpha1_role.yaml) |\n[Teams](config/crd/bases/tower.ansible.com_teams.yaml) | [team](roles/team/defaults/main.yml) | [Team](config/samples/tower_v1alpha1_team.yaml) |\n[Users](config/crd/bases/tower.ansible.com_users.yaml) | [user](roles/user/defaults/main.yml) | [User](config/samples/tower_v1alpha1_user.yaml) |\n\n\n \u003e The following CRDs have the structure but are not yet fully implemented:\n\n| Custom Resource Definition | Implementation | Custom Resource Example |\n|-|-|-|\n[Notification](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [notification](roles/jobtemplate/defaults/main.yml) |\n[Schedule](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [jobtemplate](roles/jobtemplate/defaults/main.yml) |\n[WorkflowJobTemplateNode](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [jobtemplate](roles/jobtemplate/defaults/main.yml) |\n[WorkflowJobTemplate](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [jobtemplate](roles/jobtemplate/defaults/main.yml) |\n[WorkflowTemplate](config/crd/bases/tower.ansible.com_jobtemplates.yaml) | [jobtemplate](roles/jobtemplate/defaults/main.yml) |\n\n\n## [Variables](https://sdk.operatorframework.io/docs/building-operators/ansible/development-tips/#extra-vars-sent-to-ansible)\n------------\n\nThe extra vars that are sent to Ansible are managed by the operator. The spec section will pass along the key-value pairs as extra vars. This is equivalent to how above extra vars are passed in to ansible-playbook. The operator also passes along additional variables under the ansible_operator_meta field for the name of the CR and the namespace of the CR.  \n\nFor the CR example:  \n\n```YAML\n---\napiVersion: tower.ansible.com/v1alpha1\nkind: Organization\nmetadata:\n  name: \"organization-sample\"\nspec:\n  secret: toweraccess\n  config:\n    name: \"{{ ansible_operator_meta.name }}\"\n    description: \"sample\"\n\n```  \n\nThe structure passed to Ansible as extra vars is:\n\n```JSON\n{ \"ansible_operator_meta\": {\n        \"name\": \"\u003ccr-name\u003e\",\n        \"namespace\": \"\u003ccr-namespace\u003e\",\n  },\n  \"secret\": \"toweraccess\",\n  \"config\": {\n    \"name\": \"{{ ansible_operator_meta.name }}\",\n    \"description\": \"sample\"\n  },\n  \"_tower_ansible_com_organization\": {\n     \u003cFull CR\u003e\n   },\n  \"_tower_ansible_com_organization_spec\": {\n     \u003cFull CR .spec\u003e\n   },\n}\n```\n\n`message` and `newParameter` are set in the top level as extra variables, and `ansible_operator_meta` provides the relevant metadata for the Custom Resource as defined in the operator.\n\n\n## Examples\n----------------\n\nIn this example we'll cover about how to create an organization in our Tower instance, using Organization CRD.  \nFirst we have to create generate a token in order to be able to access Tower. We can do so using curl, as per example below:\n\n```shell\ncurl -XPOST -k -H \"Content-type: application/json\" -d '{\"description\":\"Personal Tower CLI token\", \"application\":null, \"scope\":\"write\"}' https://admin:mypassword@tower.k8s.victorock.io/api/v2/users/admin/personal_tokens/ | jq\n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n100   588  100   509  100    79    180     28  0:00:02  0:00:02 --:--:--   208\n{\n  \"id\": 3,\n  \"type\": \"o_auth2_access_token\",\n  \"url\": \"/api/v2/tokens/3/\",\n  \"related\": {\n    \"user\": \"/api/v2/users/3/\",\n    \"activity_stream\": \"/api/v2/tokens/3/activity_stream/\"\n  },\n  \"summary_fields\": {\n    \"user\": {\n      \"id\": 3,\n      \"username\": \"admin\",\n      \"first_name\": \"\",\n      \"last_name\": \"\"\n    }\n  },\n  \"created\": \"2020-12-02T22:41:44.381981Z\",\n  \"modified\": \"2020-12-02T22:41:44.745244Z\",\n  \"description\": \"Personal Tower CLI token\",\n  \"user\": 3,\n  \"token\": \"LVckHx2g187SDdEAcUmsgUKjknFgWd\",\n  \"refresh_token\": null,\n  \"application\": null,\n  \"expires\": \"3020-04-04T22:41:44.256763Z\",\n  \"scope\": \"write\"\n}\n```\n\u003e NOTE: The `jq` is not required, it is used here just to help with a more human-readable output.\n\nBased on the output, note that we have the token (`LVckHx2g187SDdEAcUmsgUKjknFgWd`) has been generated by Tower, so we can do API calls to Tower without having to share usernames and passwords. As general guideline, you shall consider creating one token per application accessing your Tower.\n\nNow that we have the token to access tower, we need to create a secret in our Kubernetes environment, so the operator can use to communicate with our tower instances. The `namespace` corresponds to the namespace where the other CRs will be created, the `name` is the name for the secret, the `token` is the token generated by Tower in our previous command, and finally the `verify_ssl` is to specify if we want or not to verify the ssl certificate when doing api requests.\n\n```bash\ncat \u003c\u003cEOF | kubectl apply -f -\napiVersion: v1\nkind: Secret\nmetadata:\n  name: admin-tower.victorock.io\n  namespace: ansible-platform\ntype: Opaque\nstringData:\n  token: \"LVckHx2g187SDdEAcUmsgUKjknFgWd\"\n  host: \"https://tower.victorock.io\"\n  verify_ssl: \"false\"\nEOF\n```\n\n\u003e NOTE: CRs will have an annotation with `tower.ansible.com/host: \u003chost\u003e`\n\nWith the credentials, we can start to create the CRs which represents the different configurations that we want to have applied in Tower. The example below shows the most basic CRs, the [Organization](config/samples/tower_v1alpha1_organization.yaml) and [Project](config/samples/tower_v1alpha1_project.yaml).\n\n\n```YAML\n---\napiVersion: tower.ansible.com/v1alpha1\nkind: Organization\nmetadata:\n  name: organization-sample\nspec:\n  secret: admin-tower.victorock.io\n  config:\n    name: \"{{ ansible_operator_meta.name }}\"\n    description: \"Organization\"\n---\napiVersion: tower.ansible.com/v1alpha1\nkind: Project\nmetadata:\n  name: project-sample\nspec:\n  secret: admin-tower.victorock.io\n  config:\n    name: \"{{ ansible_operator_meta.name }}\"\n    scm_url: \"https://github.com/victorock/ansible-devops/\"\n    scm_delete_on_update: no\n    scm_type: git\n    scm_update_on_launch: true\n    organization: \"organization-sample\"\n\n```\n\n\u003e You can save these CRs definitions in a single file, or in multiple files. Once they are saved, we use the `kubectl` command to apply them to our cluster.\n\n```bash\nkubectl apply -f \u003cmyfile\u003e.yml\n```\n\n\u003e You can save these CRs definitions in files, organized in multilevel directories. Once they are saved, we use the `kubectl` command with the recursive option to apply them to our cluster.\n\n```bash\nkubectl apply -f \u003cmydir\u003e/ -R\n```\n----\n\u003e NOTE: If you want to adopt a more gitops approach, and build a pipeline to get these definitions either in one or multiple clusters, that's exactly what i am doing in this example [here](https://github.com/victorock/k8s-gitops/).\n----\n\nTODO\n-------\n\n* Tests based on [ansible-role-tower-config](https://github.com/victorock/ansible-role-tower-config)\n* Implementation of additional Tower CRDs: Settings, License, Workflow*\n* Add additional tasks to delete all dependent CRDs when organization is deleted (finalized).\n* Add strict mode capabilities, where only CRs configuration are kept.\n* Refine the CRDs specifications based on docstring of Tower's modules.\n* Refine the CRDs specifications based on the implementation asserts.\n\nLicense\n-------\n\nGPLv3\n\nAuthor Information\n------------------\n\nVictor da Costa\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorock%2Fansible-operator-tower-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvictorock%2Fansible-operator-tower-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorock%2Fansible-operator-tower-config/lists"}