├── .github └── workflows │ ├── banned_file_changes_pr.yml │ ├── cla.yml │ ├── license_audit.yml │ ├── release-zip-file.yml │ ├── repolinter.yml │ └── sonarcloud.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── artifact.tf ├── build_run.tf ├── buildpipeline.tf ├── buildstage_build.tf ├── buildstage_deliver.tf ├── buildstage_deploy.tf ├── coderepo.tf ├── datasources.tf ├── deploy_pipeline.tf ├── devops.tf ├── git-askpass-helper.sh ├── license_policy.yml ├── manifest └── gettingstarted-manifest.yaml ├── oke-network.tf ├── oke-outputs.tf ├── oke-policies.tf ├── oke-security-lists.tf ├── oke-variables.tf ├── oke.tf ├── orm ├── provider.tf └── variables.tf ├── policies.tf ├── provider.tf ├── release_files.json ├── repolinter.json ├── schema.yaml ├── sonar-project.properties ├── tags.tf └── variables.tf /.github/workflows/banned_file_changes_pr.yml: -------------------------------------------------------------------------------- 1 | name: Banned file changes (PR) 2 | on: 3 | # pull_request: 4 | # branches: [ "**/*" ] 5 | pull_request_target: 6 | 7 | jobs: 8 | check_for_banned_file_changes: 9 | name: Look for unsupported (banned) file modifications on PRs 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: 'Get number of git commits' 13 | uses: oracle-devrel/action-git-num-commits@v0.1-alpha6 14 | id: num_commits 15 | with: 16 | pull_url: ${{ github.event.pull_request.url }} 17 | - name: 'Checkout repo' 18 | uses: actions/checkout@v2 19 | with: 20 | ref: ${{ github.event.pull_request.head.ref }} 21 | repository: ${{ github.event.pull_request.head.repo.full_name }} 22 | fetch-depth: ${{ steps.num_commits.outputs.fetch_depth }} 23 | - name: Get file changes 24 | uses: oracle-devrel/action-git-files-changed@v0.1-alpha2 25 | id: files 26 | with: 27 | pull_url: ${{ github.event.pull_request.url }} 28 | - name: Look for changes to .github 29 | if: contains(steps.files.outputs.all_files_changed, '.github') 30 | run: | 31 | echo 'Changes to files in .github are not allowed.' 32 | - name: Comment if .github changed 33 | if: contains(steps.files.outputs.all_files_changed, '.github') 34 | uses: mshick/add-pr-comment@v1 35 | with: 36 | message: | 37 | :no_entry: **Banned Files Modified** 38 | Changes to files in `.github` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 39 | repo-token: ${{ secrets.GITHUB_TOKEN }} 40 | - name: Look for changes to license_policy.yml 41 | if: contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') 42 | run: | 43 | echo 'Changes to license_policy.yml are not allowed.' 44 | - name: Comment if license_policy.yml changed 45 | if: contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') 46 | uses: mshick/add-pr-comment@v1 47 | with: 48 | message: | 49 | :no_entry: **Banned Files Modified** 50 | Changes to `license_policy.yml` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 51 | repo-token: ${{ secrets.GITHUB_TOKEN }} 52 | - name: Look for changes to repolinter.json 53 | if: contains(steps.files.outputs.all_files_changed, '"repolinter.json"') 54 | uses: mshick/add-pr-comment@v1 55 | with: 56 | message: | 57 | :no_entry: **Banned Files Modified** 58 | Changes to `repolinter.json` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 59 | repo-token: ${{ secrets.GITHUB_TOKEN }} 60 | - name: Comment if repolinter.json changed 61 | if: contains(steps.files.outputs.all_files_changed, '"repolinter.json"') 62 | run: | 63 | echo 'Changes to repolinter.json are not allowed.' 64 | - name: Look for changes to sonar-project.properties 65 | if: contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 66 | uses: mshick/add-pr-comment@v1 67 | with: 68 | message: | 69 | :no_entry: **Banned Files Modified** 70 | Changes to `sonar-project.properties` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 71 | repo-token: ${{ secrets.GITHUB_TOKEN }} 72 | - name: Comment if sonar-project.properties changed 73 | if: contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 74 | run: | 75 | echo 'Changes to sonar-project.properties are not allowed.' 76 | - name: Fail on banned file changes 77 | if: contains(steps.files.outputs.all_files_changed, '.github') || contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') || contains(steps.files.outputs.all_files_changed, '"repolinter.json"') || contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 78 | run: | 79 | exit 1 -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Assistant" 2 | on: 3 | issue_comment: 4 | types: [created] 5 | pull_request_target: 6 | types: [opened,closed,synchronize] 7 | 8 | jobs: 9 | CLAssistant: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "CLA Assistant" 13 | if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' 14 | # Beta Release 15 | uses: cla-assistant/github-action@v2.1.2-beta 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | # the below token should have repo scope and must be manually added by you in the repository's secret 19 | PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }} 20 | with: 21 | # for per-repo CLA-acceptance: 22 | # path-to-signatures: 'signatures/oca-20210504/${{ github.repository }}' 23 | # for per-GHO CLA-acceptance: 24 | path-to-signatures: 'signatures/oca-20210504/oracledevrel' 25 | path-to-document: 'https://github.com/oracledevrel/devrel-oca-mgmt/blob/main/oca-20210504.md' # e.g. a CLA or a DCO document 26 | # branch should not be protected 27 | branch: 'main' 28 | allowlist: bot* 29 | 30 | #below are the optional inputs - If the optional inputs are not given, then default values will be taken 31 | remote-organization-name: "oracledevrel" # enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository) 32 | remote-repository-name: "devrel-oca-mgmt" # enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository) 33 | #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' 34 | #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' 35 | #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' 36 | #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' 37 | #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' 38 | #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) 39 | #use-dco-flag: true - If you are using DCO instead of CLA 40 | -------------------------------------------------------------------------------- /.github/workflows/license_audit.yml: -------------------------------------------------------------------------------- 1 | name: Audit licenses 2 | on: 3 | pull_request_target: 4 | 5 | jobs: 6 | run_scancode_toolkit: 7 | name: Get inventory of licenses used in project 8 | runs-on: ubuntu-latest 9 | container: 10 | image: ghcr.io/oracledevrel/scancode-toolkit:v21.3.31 11 | credentials: 12 | username: ${{ github.actor }} 13 | password: ${{ secrets.GHCR_PAT }} 14 | steps: 15 | - name: 'Checkout repo' 16 | uses: actions/checkout@v2 17 | with: 18 | ref: ${{ github.event.pull_request.head.ref }} 19 | repository: ${{ github.event.pull_request.head.repo.full_name }} 20 | - name: Run Scancode-toolkit 21 | run: | 22 | scancode -l --ignore licenses.json --ignore .github/**/* --ignore license_policy.yml --license-policy license_policy.yml --only-findings --summary --json-pp licenses.json * 23 | echo "\n\nHere is the licenses.json:\n" 24 | echo $(cat licenses.json) 25 | - name: Look for non-approved licenses 26 | uses: oracle-devrel/action-license-audit@1.0.2 27 | id: analysis 28 | with: 29 | licenses_file: '/github/workspace/licenses.json' 30 | - name: Analysis results 31 | run: echo "${{ steps.analysis.outputs.unapproved_licenses }}" 32 | - name: Comment if analysis finds unapproved licenses 33 | if: steps.analysis.outputs.unapproved_licenses == 'true' 34 | uses: mshick/add-pr-comment@v1 35 | with: 36 | message: | 37 | :no_entry: **License Inspection** 38 | Requires manual inspection. There are some licenses which dictate further analysis and review. 39 | repo-token: ${{ secrets.GITHUB_TOKEN }} 40 | - name: Halt pipeline on unapproved licenses 41 | if: steps.analysis.outputs.unapproved_licenses == 'true' 42 | run: exit 1 43 | -------------------------------------------------------------------------------- /.github/workflows/release-zip-file.yml: -------------------------------------------------------------------------------- 1 | name: Release ZIP file packaging 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | create_zip: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: 'Checkout repo' 12 | uses: actions/checkout@v2 13 | - name: 'Make (and upload) ZIP file(s)' 14 | uses: oracle-devrel/action-release-zip-maker@v0.5 15 | id: zip_maker 16 | with: 17 | github_token: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/repolinter.yml: -------------------------------------------------------------------------------- 1 | name: Repolinter 2 | on: 3 | pull_request_target: 4 | jobs: 5 | run_repolinter: 6 | name: Run Repolinter on pull request 7 | runs-on: ubuntu-latest 8 | container: 9 | image: ghcr.io/oracledevrel/repolinter:v0.11.1 10 | credentials: 11 | username: ${{ github.actor }} 12 | password: ${{ secrets.GHCR_PAT }} 13 | steps: 14 | - name: 'Checkout repo' 15 | uses: actions/checkout@v2 16 | with: 17 | ref: ${{ github.event.pull_request.head.ref }} 18 | repository: ${{ github.event.pull_request.head.repo.full_name }} 19 | - name: Run Repolinter 20 | run: | 21 | set +e 22 | bundle exec /app/bin/repolinter.js lint --format json --rulesetFile repolinter.json . > repolinter_results.json 23 | echo "\n\nHere is the repolinter_results.json:\n" 24 | echo $(cat repolinter_results.json) 25 | exit 0 26 | - name: Analyze the Repolinter results 27 | uses: oracle-devrel/action-repolinter-audit@v0.1-alpha2 28 | id: analysis 29 | with: 30 | json_results_file: '/github/workspace/repolinter_results.json' 31 | - name: Overall analysis results 32 | run: | 33 | echo "Passed: ${{ steps.analysis.outputs.passed }}" 34 | echo "Errored: ${{ steps.analysis.outputs.errored }}" 35 | - name: Comment if analysis finds missing disclaimer 36 | if: steps.analysis.outputs.disclaimer_found == 'false' 37 | uses: mshick/add-pr-comment@v1 38 | with: 39 | message: | 40 | :no_entry: **FAILURE: Missing Disclaimer** 41 | The standard Oracle Disclaimer seems to be missing from the readme. Please add it: 42 | 43 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 44 | 45 | Details: 46 | ${{ steps.analysis.outputs.disclaimer_details }} 47 | repo-token: ${{ secrets.GITHUB_TOKEN }} 48 | - name: Comment if analysis finds missing readme 49 | if: steps.analysis.outputs.readme_file_found == 'false' 50 | uses: mshick/add-pr-comment@v1 51 | with: 52 | message: | 53 | :no_entry: **FAILURE: Missing README** 54 | The README file seems to be missing. Please add it. 55 | 56 | Details: 57 | ${{ steps.analysis.outputs.readme_file_details }} 58 | repo-token: ${{ secrets.GITHUB_TOKEN }} 59 | - name: Comment if analysis finds missing license 60 | if: steps.analysis.outputs.license_file_found == 'false' 61 | uses: mshick/add-pr-comment@v1 62 | with: 63 | message: | 64 | :no_entry: **FAILURE: Missing LICENSE** 65 | The LICENSE file seems to be missing. Please add it. 66 | 67 | Details: 68 | ${{ steps.analysis.outputs.license_file_details }} 69 | repo-token: ${{ secrets.GITHUB_TOKEN }} 70 | - name: Comment if analysis finds copyright notice missing 71 | if: steps.analysis.outputs.copyright_found == 'false' 72 | uses: mshick/add-pr-comment@v1 73 | with: 74 | message: | 75 | :warning: **WARNING: Missing Copyright Notice(s)** 76 | It's a good idea to have copyright notices at the top of each file. It looks like at least one file was missing this (though it might be further down in the file - this might be a false-positive). 77 | 78 | Details: 79 | ${{ steps.analysis.outputs.copyright_details }} 80 | repo-token: ${{ secrets.GITHUB_TOKEN }} 81 | - name: Halt pipeline if README is missing 82 | if: steps.analysis.outputs.readme_file_found == 'false' 83 | run: exit 1 84 | - name: Halt pipeline if LICENSE is missing 85 | if: steps.analysis.outputs.license_file_found == 'false' 86 | run: exit 1 87 | - name: Halt pipeline if disclaimer is missing 88 | if: steps.analysis.outputs.disclaimer_found == 'false' 89 | run: exit 1 90 | -------------------------------------------------------------------------------- /.github/workflows/sonarcloud.yml: -------------------------------------------------------------------------------- 1 | name: SonarCloud Scan 2 | on: 3 | pull_request_target: 4 | jobs: 5 | sonarcloud: 6 | name: SonarCloud 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout repo 10 | uses: actions/checkout@v2 11 | with: 12 | ref: ${{ github.event.pull_request.head.ref }} 13 | repository: ${{ github.event.pull_request.head.repo.full_name }} 14 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 15 | - name: SonarCloud Scan 16 | uses: SonarSource/sonarcloud-github-action@master 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 19 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | **/.DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Local .terraform directories 7 | **/.terraform/* 8 | 9 | # .tfstate files 10 | *.tfstate 11 | *.tfstate.* 12 | *.zip* 13 | *.tfvars 14 | 15 | # terraform lock file 16 | **/.terraform.lock.hcl 17 | 18 | # Icon must end with two \r 19 | Icon 20 | 21 | # downloaded repos 22 | oci-devops-node 23 | 24 | # Thumbnails 25 | ._* 26 | 27 | # Files that might appear in the root of a volume 28 | .DocumentRevisions-V100 29 | .fseventsd 30 | .Spotlight-V100 31 | .TemporaryItems 32 | .Trashes 33 | .VolumeIcon.icns 34 | .com.apple.timemachine.donotpresent 35 | 36 | # Directories potentially created on remote AFP share 37 | .AppleDB 38 | .AppleDesktop 39 | Network Trash Folder 40 | Temporary Items 41 | .apdisk 42 | 43 | # ignore common security keys 44 | *.key 45 | *.crt 46 | *.csr 47 | *.pem -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate. 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-oci-arch-ci-cd-devops 2 | 3 | Rapid delivery of software is essential for efficiently running your applications in the cloud. Oracle Cloud Infrastructure (OCI) DevOps services provide a continuous integration and deployment (CI/CD) platform for developers to easily build, test, and deploy software and applications on Oracle Cloud. 4 | 5 | This reference architecture builds and tests a sample Node.js web application and then deploys it to OKE by using the OCI DevOps. The application source code is hosted on a DevOps code repository. The end user commits the code into the code repository, which triggers the start of a build pipeline. 6 | 7 | The build pipeline follows a user-defined flow to build and test software, then create a container image of the latest version of the application. The output of the build is stored in the container registry as an image. Then a deployment pipeline uses the built image from the container registry and a Kubernetes manifest to deploy the most recent version of the application to OKE. 8 | 9 | 10 | For details of the architecture, see [Build a continuous integration and deployment pipeline using Oracle DevOps service](https://docs.oracle.com/en/solutions/ci-cd-pipe-oci-devops/index.html) 11 | 12 | ## Terraform Provider for Oracle Cloud Infrastructure 13 | The OCI Terraform Provider is now available for automatic download through the Terraform Provider Registry. 14 | For more information on how to get started view the [documentation](https://www.terraform.io/docs/providers/oci/index.html) 15 | and [setup guide](https://www.terraform.io/docs/providers/oci/guides/version-3-upgrade.html). 16 | 17 | * [Documentation](https://www.terraform.io/docs/providers/oci/index.html) 18 | * [OCI forums](https://cloudcustomerconnect.oracle.com/resources/9c8fa8f96f/summary) 19 | * [Github issues](https://github.com/terraform-providers/terraform-provider-oci/issues) 20 | * [Troubleshooting](https://www.terraform.io/docs/providers/oci/guides/guides/troubleshooting.html) 21 | 22 | ## Deploy Using Oracle Resource Manager 23 | 24 | 1. Click [![Deploy to Oracle Cloud](https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg)](https://cloud.oracle.com/resourcemanager/stacks/create?region=home&zipUrl=https://github.com/oracle-devrel/terraform-oci-arch-ci-cd-devops/releases/latest/download/terraform-oci-arch-ci-cd-devops-stack-latest.zip) 25 | 26 | If you aren't already signed in, when prompted, enter the tenancy and user credentials. 27 | 28 | 2. Review and accept the terms and conditions. 29 | 30 | 3. Select the region where you want to deploy the stack. 31 | 32 | 4. Follow the on-screen prompts and instructions to create the stack. 33 | 34 | 5. After creating the stack, click **Terraform Actions**, and select **Plan**. 35 | 36 | 6. Wait for the job to be completed, and review the plan. 37 | 38 | To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. 39 | 40 | 7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. 41 | 42 | ## Deploy Using the Terraform CLI 43 | 44 | ### Clone the Module 45 | 46 | Now, you'll want a local copy of this repo. You can make that with the commands: 47 | 48 | git clone https://github.com/oracle-devrel/terraform-oci-arch-ci-cd-devops 49 | cd terraform-oci-arch-ci-cd-devops 50 | ls 51 | 52 | ### Prerequisites 53 | First off, you'll need to do some pre-deploy setup. That's all detailed [here](https://github.com/cloud-partners/oci-prerequisites). 54 | 55 | Secondly, create a `terraform.tfvars` file and populate with the following information: 56 | 57 | ``` 58 | # Authentication 59 | tenancy_ocid = "" 60 | user_ocid = "" 61 | fingerprint = "" 62 | private_key_path = "" 63 | 64 | # Region 65 | region = "" 66 | 67 | # Compartment 68 | compartment_ocid = "" 69 | 70 | # OCI User and Authtoken 71 | oci_username = " 72 | # For a federated user (single sign-on with an identity provider), enter the username in the following format: TenancyName/Federation/UserName. 73 | # For example, if you use OCI's identity provider, your login would be, Acme/oracleidentitycloudservice/alice.jones@acme.com. 74 | #If you are using OCI's direct sign-in, enter the username in the following format: TenancyName/YourUserName. For example, Acme/alice_jones. Your password is the auth token you created previously. 75 | 76 | oci_user_authtoken = "" 77 | # You can get the auth token from your Profile menu -> click User Settings -> On left side click *Auth Tokens -> Generate Token 78 | 79 | ``` 80 | 81 | Deploy: 82 | 83 | terraform init 84 | terraform plan 85 | terraform apply 86 | 87 | 88 | ## Access the application 89 | You can go to created OKE cluster, click on `Access Cluster`, launch `Cloud Shell`, run `kubeconfig` create command in cloud shell. 90 | 91 | Next, run the below command. 92 | 93 | `kubectl -n example get services` 94 | 95 | - where `example` is the namespace for the cluster. 96 | 97 | You can copy the `EXTERNAL-IP` and paste it on the browser to access the Node.JS application. 98 | 99 | ## Destroy the Deployment 100 | When you no longer need the deployment, you can run this command to destroy it: 101 | 102 | terraform destroy 103 | 104 | Note: Application deployment within OKE will lead to OCI LoadBalancer provisioning, created outside the Terraform realm. Consequently, terraform destroy operation will not be able to destroy OKE as dependent LB will stay untouched. Therefore you should destroy LB from OCI Console perspective beforehand. Then you can continue with terraform destroy command. 105 | 106 | ## Attribution & Credits 107 | Initially, this project was created and distributed in [GitHub Oracle QuickStart space](https://github.com/oracle-quickstart). For that reason, we would like to thank all the involved contributors enlisted below: 108 | - Kartik Hedge (https://github.com/KartikShrikantHedge) 109 | - Lukasz Feldman (https://github.com/lfeldman) 110 | - Nuno Gonçalves (https://github.com/nugoncal) 111 | 112 | ## License 113 | Copyright (c) 2024 Oracle and/or its affiliates. 114 | 115 | Licensed under the Universal Permissive License (UPL), Version 1.0. 116 | 117 | See [LICENSE](LICENSE.txt) for more details. 118 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /artifact.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_artifacts_container_repository" "test_container_repository" { 5 | #Required 6 | compartment_id = var.compartment_ocid 7 | display_name = "node-express-getting-starter-${random_id.tag.hex}" 8 | #Optional 9 | is_public = var.container_repository_is_public 10 | } 11 | 12 | resource "oci_devops_deploy_artifact" "test_deploy_artifact" { 13 | 14 | #Required 15 | argument_substitution_mode = var.deploy_artifact_argument_substitution_mode 16 | deploy_artifact_source { 17 | #Required 18 | deploy_artifact_source_type = var.deploy_artifact_deploy_artifact_source_deploy_artifact_source_type 19 | 20 | #Optional 21 | image_uri = "${local.ocir_docker_repository}/${local.ocir_namespace}/${oci_artifacts_container_repository.test_container_repository.display_name}:$${BUILDRUN_HASH}" 22 | image_digest = " " 23 | #image_digest = oci_devops_build_run.test_build_run.build_outputs[0].delivered_artifacts[0].items[0].delivered_artifact_hash 24 | repository_id = oci_devops_repository.test_repository.id 25 | } 26 | 27 | deploy_artifact_type = var.deploy_artifact_deploy_artifact_type 28 | project_id = oci_devops_project.test_project.id 29 | 30 | #Optional 31 | display_name = "${oci_artifacts_container_repository.test_container_repository.display_name}" 32 | } 33 | -------------------------------------------------------------------------------- /build_run.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_build_run" "test_build_run_1" { 5 | 6 | depends_on = [oci_devops_build_pipeline_stage.test_build_pipeline_stage, 7 | oci_devops_build_pipeline_stage.test_deliver_artifact_stage, 8 | oci_devops_build_pipeline_stage.test_deploy_stage, 9 | oci_devops_deploy_stage.test_deploy_stage, 10 | module.oci-oke[0].node_pool] 11 | 12 | #Required 13 | build_pipeline_id = oci_devops_build_pipeline.test_build_pipeline.id 14 | 15 | #Optional 16 | display_name = "build_run_${random_id.tag.hex}" 17 | 18 | provisioner "local-exec" { 19 | command = "sleep 300" 20 | } 21 | 22 | } 23 | 24 | # output "build_digest_output" { 25 | # value = oci_devops_build_run.test_build_run.build_outputs[0].delivered_artifacts[0].items[0].delivered_artifact_hash 26 | # } -------------------------------------------------------------------------------- /buildpipeline.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_build_pipeline" "test_build_pipeline" { 5 | 6 | #Required 7 | project_id = oci_devops_project.test_project.id 8 | 9 | description = var.build_pipeline_description 10 | display_name = var.build_pipeline_display_name 11 | } 12 | 13 | -------------------------------------------------------------------------------- /buildstage_build.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_build_pipeline_stage" "test_build_pipeline_stage" { 5 | #Required 6 | build_pipeline_id = oci_devops_build_pipeline.test_build_pipeline.id 7 | build_pipeline_stage_predecessor_collection { 8 | #Required 9 | items { 10 | #Required 11 | id = oci_devops_build_pipeline.test_build_pipeline.id 12 | } 13 | } 14 | build_pipeline_stage_type = var.build_pipeline_stage_build_pipeline_stage_type 15 | 16 | #Optional 17 | build_source_collection { 18 | 19 | #Optional 20 | items { 21 | #Required 22 | connection_type = var.build_pipeline_stage_build_source_collection_items_connection_type 23 | 24 | #Optional 25 | branch = var.build_pipeline_stage_build_source_collection_items_branch 26 | # connection_id = oci_devops_connection.test_connection.id 27 | name = var.build_pipeline_stage_build_source_collection_items_name 28 | repository_id = oci_devops_repository.test_repository.id 29 | repository_url = "https://devops.scmservice.${var.region}.oci.oraclecloud.com/namespaces/${local.ocir_namespace}/projects/${oci_devops_project.test_project.name}/repositories/${oci_devops_repository.test_repository.name}" 30 | } 31 | } 32 | 33 | build_spec_file = var.build_pipeline_stage_build_spec_file 34 | description = var.build_pipeline_stage_description 35 | display_name = var.build_pipeline_stage_display_name 36 | image = var.build_pipeline_stage_image 37 | stage_execution_timeout_in_seconds = var.build_pipeline_stage_stage_execution_timeout_in_seconds 38 | wait_criteria { 39 | #Required 40 | wait_duration = var.build_pipeline_stage_wait_criteria_wait_duration 41 | wait_type = var.build_pipeline_stage_wait_criteria_wait_type 42 | } 43 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /buildstage_deliver.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_build_pipeline_stage" "test_deliver_artifact_stage" { 5 | 6 | depends_on = [oci_devops_build_pipeline_stage.test_build_pipeline_stage] 7 | 8 | #Required 9 | build_pipeline_id = oci_devops_build_pipeline.test_build_pipeline.id 10 | build_pipeline_stage_predecessor_collection { 11 | #Required 12 | items { 13 | #Required 14 | id = oci_devops_build_pipeline_stage.test_build_pipeline_stage.id 15 | } 16 | } 17 | 18 | build_pipeline_stage_type = var.build_pipeline_stage_deliver_artifact_stage_type 19 | 20 | deliver_artifact_collection { 21 | 22 | #Optional 23 | items { 24 | #Optional 25 | artifact_id = oci_devops_deploy_artifact.test_deploy_artifact.id 26 | artifact_name = var.build_pipeline_stage_deliver_artifact_collection_items_artifact_name 27 | } 28 | } 29 | display_name = var.deliver_artifact_stage_display_name 30 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /buildstage_deploy.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | resource "oci_devops_build_pipeline_stage" "test_deploy_stage" { 6 | 7 | depends_on = [oci_devops_build_pipeline_stage.test_deliver_artifact_stage] 8 | 9 | #Required 10 | build_pipeline_id = oci_devops_build_pipeline.test_build_pipeline.id 11 | 12 | build_pipeline_stage_predecessor_collection { 13 | #Required 14 | items { 15 | #Required 16 | id = oci_devops_build_pipeline_stage.test_deliver_artifact_stage.id 17 | } 18 | } 19 | 20 | build_pipeline_stage_type = var.build_pipeline_stage_deploy_stage_type 21 | 22 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 23 | display_name = var.deploy_stage_display_name 24 | is_pass_all_parameters_enabled = var.build_pipeline_stage_is_pass_all_parameters_enabled 25 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /coderepo.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_repository" "test_repository" { 5 | #Required 6 | name = var.repository_name 7 | project_id = oci_devops_project.test_project.id 8 | 9 | #Optional 10 | default_branch = var.repository_default_branch 11 | description = var.repository_description 12 | 13 | repository_type = var.repository_repository_type 14 | } 15 | 16 | 17 | resource "null_resource" "clonerepo" { 18 | 19 | depends_on = [oci_devops_project.test_project, oci_devops_repository.test_repository] 20 | 21 | provisioner "local-exec" { 22 | command = "echo '(1) Cleaning local repo: '; rm -rf ${oci_devops_repository.test_repository.name}" 23 | } 24 | 25 | provisioner "local-exec" { 26 | command = "echo '(2) Repo to clone: https://devops.scmservice.${var.region}.oci.oraclecloud.com/namespaces/${local.ocir_namespace}/projects/${oci_devops_project.test_project.name}/repositories/${oci_devops_repository.test_repository.name}'" 27 | } 28 | 29 | #provisioner "local-exec" { 30 | # command = "echo '(3) Preparing git-askpass-helper script... '; current_dir=$PWD; chmod +x $current_dir/git-askpass-helper.sh" 31 | #} 32 | 33 | provisioner "local-exec" { 34 | command = "echo '(3) Starting git clone command... '; echo 'Username: Before' ${var.oci_username}; echo 'Username: After' ${local.encode_user}; echo 'auth_token' ${local.auth_token}; git clone https://${local.encode_user}:${local.auth_token}@devops.scmservice.${var.region}.oci.oraclecloud.com/namespaces/${local.ocir_namespace}/projects/${oci_devops_project.test_project.name}/repositories/${oci_devops_repository.test_repository.name};" 35 | } 36 | 37 | provisioner "local-exec" { 38 | command = "echo '(4) Finishing git clone command: '; ls -latr ${oci_devops_repository.test_repository.name}" 39 | } 40 | } 41 | 42 | resource "null_resource" "clonefromgithub" { 43 | 44 | provisioner "local-exec" { 45 | command = "rm -rf ./${var.git_repo_name}" 46 | } 47 | 48 | provisioner "local-exec" { 49 | command = "git clone ${var.git_repo};" 50 | } 51 | } 52 | 53 | resource "null_resource" "copyfiles" { 54 | 55 | depends_on = [null_resource.clonerepo] 56 | 57 | provisioner "local-exec" { 58 | command = "rm -rf ${var.git_repo_name}/.git; cp -pr ${var.git_repo_name}/* ${oci_devops_repository.test_repository.name}/; cd .." 59 | } 60 | } 61 | 62 | 63 | resource "null_resource" "pushcode" { 64 | 65 | depends_on = [null_resource.copyfiles] 66 | 67 | provisioner "local-exec" { 68 | command = "cd ./${oci_devops_repository.test_repository.name}; git config --local user.email 'test@example.com'; git config --local user.name '${var.oci_username}';git add .; git commit -m 'added latest files'; git push origin '${var.repository_default_branch}'" 69 | } 70 | } 71 | 72 | 73 | locals { 74 | encode_user = urlencode(var.oci_username) 75 | auth_token = urlencode(var.oci_user_authtoken) 76 | } 77 | -------------------------------------------------------------------------------- /datasources.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | data "oci_identity_availability_domains" "ADs" { 5 | compartment_id = var.tenancy_ocid 6 | } 7 | 8 | # Gets home and current regions 9 | 10 | data "oci_identity_tenancy" "tenant_details" { 11 | tenancy_id = var.tenancy_ocid 12 | provider = oci.current_region 13 | } 14 | 15 | data "oci_identity_regions" "home_region" { 16 | filter { 17 | name = "key" 18 | values = [data.oci_identity_tenancy.tenant_details.home_region_key] 19 | } 20 | 21 | provider = oci.current_region 22 | } 23 | 24 | data "oci_identity_regions" "current_region" { 25 | filter { 26 | name = "name" 27 | values = [var.region] 28 | } 29 | provider = oci.current_region 30 | } 31 | 32 | # Randoms 33 | resource "random_string" "deploy_id" { 34 | length = 4 35 | special = false 36 | } 37 | 38 | # Gets a list of supported images based on the shape, operating_system and operating_system_version provided 39 | data "oci_core_images" "node_pool_images" { 40 | compartment_id = local.oke_compartment_id 41 | operating_system = var.image_operating_system 42 | operating_system_version = var.image_operating_system_version 43 | shape = var.node_pool_shape 44 | sort_by = "TIMECREATED" 45 | sort_order = "DESC" 46 | } 47 | 48 | data "oci_containerengine_cluster_option" "oke" { 49 | cluster_option_id = "all" 50 | } 51 | data "oci_containerengine_node_pool_option" "oke" { 52 | node_pool_option_id = "all" 53 | } 54 | 55 | # OCI Services 56 | ## Available Services 57 | data "oci_core_services" "all_services" { 58 | filter { 59 | name = "name" 60 | values = ["All .* Services In Oracle Services Network"] 61 | regex = true 62 | } 63 | } 64 | 65 | ## Object Storage 66 | data "oci_objectstorage_namespace" "ns" { 67 | compartment_id = local.oke_compartment_id 68 | } 69 | 70 | # Gets kubeconfig 71 | data "oci_containerengine_cluster_kube_config" "oke_cluster_kube_config" { 72 | cluster_id = var.create_new_oke_cluster ? module.oci-oke[0].cluster.id : var.existent_oke_cluster_id 73 | } 74 | 75 | 76 | data "oci_load_balancer_load_balancers" "LBs" { 77 | compartment_id = var.compartment_ocid 78 | depends_on = [oci_devops_build_run.test_build_run_1] 79 | 80 | } 81 | -------------------------------------------------------------------------------- /deploy_pipeline.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_devops_deploy_environment" "test_environment" { 5 | display_name = "oke_environment_${random_id.tag.hex}" 6 | description = "oke based enviroment" 7 | deploy_environment_type = "OKE_CLUSTER" 8 | project_id = oci_devops_project.test_project.id 9 | cluster_id = var.create_new_oke_cluster ? module.oci-oke[0].cluster.id : var.existent_oke_cluster_id 10 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 11 | } 12 | 13 | # Add var to choose between an existing Articat and an inline one 14 | 15 | resource "oci_devops_deploy_artifact" "test_deploy_oke_artifact" { 16 | argument_substitution_mode = var.deploy_artifact_argument_substitution_mode 17 | deploy_artifact_type = var.deploy_artifact_type 18 | project_id = oci_devops_project.test_project.id 19 | 20 | deploy_artifact_source { 21 | deploy_artifact_source_type = var.deploy_artifact_source_type #INLINE,GENERIC_ARTIFACT_OCIR 22 | base64encoded_content = templatefile("${path.module}/manifest/gettingstarted-manifest.yaml", { region = "${local.ocir_docker_repository}", name = "${local.ocir_namespace}", image = "${oci_artifacts_container_repository.test_container_repository.display_name}", hash = "$${BUILDRUN_HASH}", namespace = "$${namespace}" }) 23 | } 24 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 25 | } 26 | 27 | resource "oci_devops_deploy_pipeline" "test_deploy_pipeline" { 28 | #Required 29 | project_id = oci_devops_project.test_project.id 30 | description = var.deploy_pipeline_description 31 | display_name = "devops-oke-pipeline_${random_id.tag.hex}" 32 | 33 | deploy_pipeline_parameters { 34 | items { 35 | name = var.deploy_pipeline_deploy_pipeline_parameters_items_name 36 | default_value = var.deploy_pipeline_deploy_pipeline_parameters_items_default_value 37 | description = var.deploy_pipeline_deploy_pipeline_parameters_items_description 38 | } 39 | } 40 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 41 | } 42 | 43 | resource "oci_devops_deploy_stage" "test_deploy_stage" { 44 | #Required 45 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 46 | deploy_stage_predecessor_collection { 47 | #Required 48 | items { 49 | #Required 50 | id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 51 | } 52 | } 53 | deploy_stage_type = var.deploy_stage_deploy_stage_type 54 | 55 | 56 | description = var.deploy_stage_description 57 | display_name = "deploy_to_OKE_${random_id.tag.hex}" 58 | 59 | kubernetes_manifest_deploy_artifact_ids = [oci_devops_deploy_artifact.test_deploy_oke_artifact.id] 60 | oke_cluster_deploy_environment_id = oci_devops_deploy_environment.test_environment.id 61 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 62 | } 63 | 64 | /* 65 | resource "oci_devops_deployment" "test_deployment1" { 66 | count = var.execute_deployment ? 1 : 0 67 | depends_on = [oci_devops_deploy_stage.test_deploy_stage] 68 | #Required 69 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 70 | deployment_type = "PIPELINE_DEPLOYMENT" 71 | 72 | #Optional 73 | display_name = "devopsdeployment_${random_id.tag.hex}" 74 | } 75 | */ 76 | -------------------------------------------------------------------------------- /devops.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | # Create log and log group 5 | 6 | resource "oci_logging_log_group" "test_log_group" { 7 | compartment_id = var.compartment_ocid 8 | display_name = "devops_log_group_${random_string.deploy_id.result}" 9 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 10 | } 11 | 12 | resource "oci_logging_log" "test_log" { 13 | #Required 14 | display_name = "devops_log_group_log" 15 | log_group_id = oci_logging_log_group.test_log_group.id 16 | log_type = "SERVICE" 17 | 18 | #Optional 19 | configuration { 20 | #Required 21 | source { 22 | #Required 23 | category = "all" 24 | resource = oci_devops_project.test_project.id 25 | service = "devops" 26 | source_type = "OCISERVICE" 27 | } 28 | 29 | #Optional 30 | compartment_id = var.compartment_ocid 31 | } 32 | 33 | is_enabled = true 34 | retention_duration = var.project_logging_config_retention_period_in_days 35 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 36 | } 37 | 38 | # Create OCI Notification 39 | 40 | resource "oci_ons_notification_topic" "test_notification_topic" { 41 | compartment_id = var.compartment_ocid 42 | name = "devopstopic_${random_string.deploy_id.result}" 43 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 44 | } 45 | 46 | # Create devops project 47 | 48 | resource "oci_devops_project" "test_project" { 49 | compartment_id = var.compartment_ocid 50 | name = "devopsproject_${random_string.deploy_id.result}" 51 | 52 | notification_config { 53 | #Required 54 | topic_id = oci_ons_notification_topic.test_notification_topic.id 55 | } 56 | 57 | #Optional 58 | description = var.project_description 59 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 60 | } 61 | -------------------------------------------------------------------------------- /git-askpass-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec echo "$GIT_USERNAME" 3 | exec echo "$GIT_PASSWORD" 4 | -------------------------------------------------------------------------------- /license_policy.yml: -------------------------------------------------------------------------------- 1 | license_policies: 2 | - license_key: upl-1.0 3 | label: Approved License 4 | color_code: '#00800' 5 | icon: icon-ok-circle 6 | - license_key: bsd-simplified 7 | label: Approved License 8 | color_code: '#00800' 9 | icon: icon-ok-circle 10 | - license_key: bsd-new 11 | label: Approved License 12 | color_code: '#00800' 13 | icon: icon-ok-circle 14 | - license_key: mit 15 | label: Approved License 16 | color_code: '#00800' 17 | icon: icon-ok-circle 18 | -------------------------------------------------------------------------------- /manifest/gettingstarted-manifest.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: ${namespace} 5 | --- 6 | apiVersion: apps/v1 7 | kind: Deployment 8 | metadata: 9 | name: node-gettingstarted-deployment 10 | namespace: ${namespace} 11 | spec: 12 | selector: 13 | matchLabels: 14 | app: node-gettingstarted 15 | replicas: 3 16 | template: 17 | metadata: 18 | labels: 19 | app: node-gettingstarted 20 | spec: 21 | containers: 22 | - name: node-gettingstarted 23 | # enter the path to your image, be sure to include the correct region prefix 24 | image: ${region}/${name}/${image}:${hash} 25 | imagePullPolicy: Always 26 | ports: 27 | - containerPort: 3000 28 | protocol: TCP 29 | --- 30 | apiVersion: v1 31 | kind: Service 32 | metadata: 33 | name: node-gettingstarted-service 34 | namespace: ${namespace} 35 | annotations: 36 | service.beta.kubernetes.io/oci-load-balancer-shape: "10Mbps" 37 | spec: 38 | type: LoadBalancer 39 | ports: 40 | - port: 80 41 | protocol: TCP 42 | targetPort: 3000 43 | selector: 44 | app: node-gettingstarted -------------------------------------------------------------------------------- /oke-network.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | resource "oci_core_virtual_network" "oke_vcn" { 6 | cidr_block = lookup(var.network_cidrs, "VCN-CIDR") 7 | compartment_id = local.oke_compartment_id 8 | display_name = "OKE-VCN-${random_string.deploy_id.result}" 9 | dns_label = "oke${random_string.deploy_id.result}" 10 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 11 | 12 | count = var.create_new_oke_cluster ? 1 : 0 13 | } 14 | 15 | resource "oci_core_subnet" "oke_k8s_endpoint_subnet" { 16 | cidr_block = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 17 | compartment_id = local.oke_compartment_id 18 | display_name = "oke-k8s-endpoint-subnet-${random_string.deploy_id.result}" 19 | dns_label = "okek8sn${random_string.deploy_id.result}" 20 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 21 | prohibit_public_ip_on_vnic = (var.cluster_endpoint_visibility == "Private") ? true : false 22 | route_table_id = (var.cluster_endpoint_visibility == "Private") ? oci_core_route_table.oke_private_route_table[0].id : oci_core_route_table.oke_public_route_table[0].id 23 | dhcp_options_id = oci_core_virtual_network.oke_vcn[0].default_dhcp_options_id 24 | security_list_ids = [oci_core_security_list.oke_endpoint_security_list[0].id] 25 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 26 | 27 | 28 | count = var.create_new_oke_cluster ? 1 : 0 29 | } 30 | resource "oci_core_subnet" "oke_nodes_subnet" { 31 | cidr_block = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 32 | compartment_id = local.oke_compartment_id 33 | display_name = "oke-nodes-subnet-${random_string.deploy_id.result}" 34 | dns_label = "okenodesn${random_string.deploy_id.result}" 35 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 36 | prohibit_public_ip_on_vnic = (var.cluster_workers_visibility == "Private") ? true : false 37 | route_table_id = (var.cluster_workers_visibility == "Private") ? oci_core_route_table.oke_private_route_table[0].id : oci_core_route_table.oke_public_route_table[0].id 38 | dhcp_options_id = oci_core_virtual_network.oke_vcn[0].default_dhcp_options_id 39 | security_list_ids = [oci_core_security_list.oke_nodes_security_list[0].id] 40 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 41 | 42 | count = var.create_new_oke_cluster ? 1 : 0 43 | } 44 | 45 | resource "oci_core_subnet" "oke_lb_subnet" { 46 | cidr_block = lookup(var.network_cidrs, "LB-SUBNET-REGIONAL-CIDR") 47 | compartment_id = local.oke_compartment_id 48 | display_name = "oke-lb-subnet-${random_string.deploy_id.result}" 49 | dns_label = "okelbsn${random_string.deploy_id.result}" 50 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 51 | prohibit_public_ip_on_vnic = false 52 | route_table_id = oci_core_route_table.oke_public_route_table[0].id 53 | dhcp_options_id = oci_core_virtual_network.oke_vcn[0].default_dhcp_options_id 54 | security_list_ids = [oci_core_security_list.oke_lb_security_list[0].id] 55 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 56 | 57 | 58 | count = var.create_new_oke_cluster ? 1 : 0 59 | } 60 | 61 | resource "oci_core_route_table" "oke_private_route_table" { 62 | compartment_id = local.oke_compartment_id 63 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 64 | display_name = "oke-private-route-table-${random_string.deploy_id.result}" 65 | 66 | route_rules { 67 | description = "Traffic to the internet" 68 | destination = lookup(var.network_cidrs, "ALL-CIDR") 69 | destination_type = "CIDR_BLOCK" 70 | network_entity_id = oci_core_nat_gateway.oke_nat_gateway[0].id 71 | } 72 | route_rules { 73 | description = "Traffic to OCI services" 74 | destination = lookup(data.oci_core_services.all_services.services[0], "cidr_block") 75 | destination_type = "SERVICE_CIDR_BLOCK" 76 | network_entity_id = oci_core_service_gateway.oke_service_gateway[0].id 77 | } 78 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 79 | 80 | count = var.create_new_oke_cluster ? 1 : 0 81 | } 82 | 83 | resource "oci_core_route_table" "oke_public_route_table" { 84 | compartment_id = local.oke_compartment_id 85 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 86 | display_name = "oke-public-route-table-${random_string.deploy_id.result}" 87 | 88 | route_rules { 89 | description = "Traffic to/from internet" 90 | destination = lookup(var.network_cidrs, "ALL-CIDR") 91 | destination_type = "CIDR_BLOCK" 92 | network_entity_id = oci_core_internet_gateway.oke_internet_gateway[0].id 93 | } 94 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 95 | 96 | count = var.create_new_oke_cluster ? 1 : 0 97 | } 98 | 99 | resource "oci_core_nat_gateway" "oke_nat_gateway" { 100 | block_traffic = "false" 101 | compartment_id = local.oke_compartment_id 102 | display_name = "oke-nat-gateway-${random_string.deploy_id.result}" 103 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 104 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 105 | 106 | count = var.create_new_oke_cluster ? 1 : 0 107 | } 108 | 109 | resource "oci_core_internet_gateway" "oke_internet_gateway" { 110 | compartment_id = local.oke_compartment_id 111 | display_name = "oke-internet-gateway-${random_string.deploy_id.result}" 112 | enabled = true 113 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 114 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 115 | 116 | count = var.create_new_oke_cluster ? 1 : 0 117 | } 118 | 119 | resource "oci_core_service_gateway" "oke_service_gateway" { 120 | compartment_id = local.oke_compartment_id 121 | display_name = "oke-service-gateway-${random_string.deploy_id.result}" 122 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 123 | services { 124 | service_id = lookup(data.oci_core_services.all_services.services[0], "id") 125 | } 126 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 127 | 128 | count = var.create_new_oke_cluster ? 1 : 0 129 | } 130 | -------------------------------------------------------------------------------- /oke-outputs.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | ### Important Security Notice ### 6 | # The private key generated by this resource will be stored unencrypted in your Terraform state file. 7 | # Use of this resource for production deployments is not recommended. 8 | # Instead, generate a private key file outside of Terraform and distribute it securely to the system where Terraform will be run. 9 | output "generated_private_key_pem" { 10 | sensitive = true 11 | value = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.private_key_pem : "No Keys Auto Generated" 12 | } 13 | output "dev" { 14 | value = "Made with \u2764 by Oracle Developers" 15 | } 16 | output "comments" { 17 | value = "The application URL will be unavailable for a few minutes after provisioning while the application is configured and deployed to Kubernetes" 18 | } 19 | output "deploy_id" { 20 | value = random_string.deploy_id.result 21 | } 22 | output "deployed_to_region" { 23 | value = var.region 24 | } 25 | output "deployed_oke_kubernetes_version" { 26 | value = (var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version 27 | } 28 | output "kubeconfig_for_kubectl" { 29 | value = "export KUBECONFIG=./generated/kubeconfig" 30 | description = "If using Terraform locally, this command set KUBECONFIG environment variable to run kubectl locally" 31 | } 32 | 33 | output "LB_IP" { 34 | value = data.oci_load_balancer_load_balancers.LBs.load_balancers[0].ip_addresses 35 | } 36 | -------------------------------------------------------------------------------- /oke-policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | resource "oci_identity_dynamic_group" "oke_nodes_dg" { 6 | name = "oke-cluster-dg-${random_string.deploy_id.result}" 7 | description = "Cluster Dynamic Group" 8 | compartment_id = var.tenancy_ocid 9 | matching_rule = "ANY {ALL {instance.compartment.id = '${local.oke_compartment_id}'},ALL {resource.type = 'cluster', resource.compartment.id = '${local.oke_compartment_id}'}}" 10 | 11 | provider = oci.home_region 12 | 13 | count = var.create_dynamic_group_for_nodes_in_compartment ? 1 : 0 14 | } 15 | resource "oci_identity_policy" "oke_compartment_policies" { 16 | name = "oke-cluster-compartment-policies-${random_string.deploy_id.result}" 17 | description = "OKE Cluster Compartment Policies" 18 | compartment_id = local.oke_compartment_id 19 | statements = local.oke_compartment_statements 20 | 21 | depends_on = [oci_identity_dynamic_group.oke_nodes_dg] 22 | 23 | provider = oci.home_region 24 | 25 | count = var.create_compartment_policies ? 1 : 0 26 | } 27 | resource "oci_identity_policy" "kms_compartment_policies" { 28 | name = "kms-compartment-policies-${random_string.deploy_id.result}" 29 | description = "KMS Compartment Policies" 30 | compartment_id = local.oke_compartment_id 31 | statements = local.kms_compartment_statements 32 | 33 | depends_on = [oci_identity_dynamic_group.oke_nodes_dg] 34 | 35 | provider = oci.home_region 36 | 37 | count = (var.create_compartment_policies && var.create_vault_policies_for_group) ? 1 : 0 38 | } 39 | 40 | resource "oci_identity_policy" "oke_tenancy_policies" { 41 | name = "oke-cluster-tenancy-policies-${random_string.deploy_id.result}" 42 | description = "OKE Cluster Tenancy Policies" 43 | compartment_id = var.tenancy_ocid 44 | statements = local.oke_tenancy_statements 45 | 46 | depends_on = [oci_identity_dynamic_group.oke_nodes_dg] 47 | 48 | provider = oci.home_region 49 | 50 | count = var.create_tenancy_policies ? 1 : 0 51 | } 52 | 53 | locals { 54 | oke_tenancy_statements = concat( 55 | local.oci_grafana_metrics_statements 56 | ) 57 | oke_compartment_statements = concat( 58 | local.oci_grafana_logs_statements, 59 | var.use_encryption_from_oci_vault ? local.allow_oke_use_oci_vault_keys_statements : [] 60 | #var.cluster_autoscaler_enabled ? local.cluster_autoscaler_statements : [] 61 | ) 62 | kms_compartment_statements = concat( 63 | local.allow_group_manage_vault_keys_statements 64 | ) 65 | } 66 | 67 | locals { 68 | oke_nodes_dg = var.create_dynamic_group_for_nodes_in_compartment ? oci_identity_dynamic_group.oke_nodes_dg.0.name : "void" 69 | oci_vault_key_id = "void" 70 | #var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? oci_kms_key.mushop_key[0].id : var.existent_encryption_key_id) : "void" 71 | oci_grafana_metrics_statements = [ 72 | "Allow dynamic-group ${local.oke_nodes_dg} to read metrics in tenancy", 73 | "Allow dynamic-group ${local.oke_nodes_dg} to read compartments in tenancy" 74 | ] 75 | oci_grafana_logs_statements = [ 76 | "Allow dynamic-group ${local.oke_nodes_dg} to read log-groups in compartment id ${local.oke_compartment_id}", 77 | "Allow dynamic-group ${local.oke_nodes_dg} to read log-content in compartment id ${local.oke_compartment_id}" 78 | ] 79 | # cluster_autoscaler_statements = [ 80 | # "Allow dynamic-group ${local.oke_nodes_dg} to manage cluster-node-pools in compartment id ${local.oke_compartment_id}", 81 | # "Allow dynamic-group ${local.oke_nodes_dg} to manage instance-family in compartment id ${local.oke_compartment_id}", 82 | # "Allow dynamic-group ${local.oke_nodes_dg} to use subnets in compartment id ${local.oke_compartment_id}", 83 | # "Allow dynamic-group ${local.oke_nodes_dg} to read virtual-network-family in compartment id ${local.oke_compartment_id}", 84 | # "Allow dynamic-group ${local.oke_nodes_dg} to use vnics in compartment id ${local.oke_compartment_id}", 85 | # "Allow dynamic-group ${local.oke_nodes_dg} to inspect compartments in compartment id ${local.oke_compartment_id}" 86 | # ] 87 | allow_oke_use_oci_vault_keys_statements = [ 88 | "Allow service oke to use vaults in compartment id ${local.oke_compartment_id}", 89 | "Allow service oke to use keys in compartment id ${local.oke_compartment_id} where target.key.id = '${local.oci_vault_key_id}'", 90 | "Allow dynamic-group ${local.oke_nodes_dg} to use keys in compartment id ${local.oke_compartment_id} where target.key.id = '${local.oci_vault_key_id}'" 91 | ] 92 | allow_group_manage_vault_keys_statements = [ 93 | "Allow group ${var.user_admin_group_for_vault_policy} to manage vaults in compartment id ${local.oke_compartment_id}", 94 | "Allow group ${var.user_admin_group_for_vault_policy} to manage keys in compartment id ${local.oke_compartment_id}", 95 | "Allow group ${var.user_admin_group_for_vault_policy} to use key-delegate in compartment id ${local.oke_compartment_id}" 96 | ] 97 | } -------------------------------------------------------------------------------- /oke-security-lists.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | resource "oci_core_security_list" "oke_nodes_security_list" { 6 | compartment_id = local.oke_compartment_id 7 | display_name = "oke-nodes-wkr-seclist-${random_string.deploy_id.result}" 8 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 9 | 10 | # Ingresses 11 | ingress_security_rules { 12 | description = "Allow pods on one worker node to communicate with pods on other worker nodes" 13 | source = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 14 | source_type = "CIDR_BLOCK" 15 | protocol = local.all_protocols 16 | stateless = false 17 | } 18 | ingress_security_rules { 19 | description = "Inbound SSH traffic to worker nodes" 20 | source = lookup(var.network_cidrs, (var.cluster_workers_visibility == "Private") ? "VCN-CIDR" : "ALL-CIDR") 21 | source_type = "CIDR_BLOCK" 22 | protocol = local.tcp_protocol_number 23 | stateless = false 24 | 25 | tcp_options { 26 | max = local.ssh_port_number 27 | min = local.ssh_port_number 28 | } 29 | } 30 | ingress_security_rules { 31 | description = "TCP access from Kubernetes Control Plane" 32 | source = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 33 | source_type = "CIDR_BLOCK" 34 | protocol = local.tcp_protocol_number 35 | stateless = false 36 | } 37 | ingress_security_rules { 38 | description = "Path discovery" 39 | source = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 40 | source_type = "CIDR_BLOCK" 41 | protocol = local.icmp_protocol_number 42 | stateless = false 43 | 44 | icmp_options { 45 | type = "3" 46 | code = "4" 47 | } 48 | } 49 | 50 | # Egresses 51 | egress_security_rules { 52 | description = "Allow pods on one worker node to communicate with pods on other worker nodes" 53 | destination = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 54 | destination_type = "CIDR_BLOCK" 55 | protocol = local.all_protocols 56 | stateless = false 57 | } 58 | egress_security_rules { 59 | description = "Worker Nodes access to Internet" 60 | destination = lookup(var.network_cidrs, "ALL-CIDR") 61 | destination_type = "CIDR_BLOCK" 62 | protocol = local.all_protocols 63 | stateless = false 64 | } 65 | egress_security_rules { 66 | description = "Allow nodes to communicate with OKE to ensure correct start-up and continued functioning" 67 | destination = lookup(data.oci_core_services.all_services.services[0], "cidr_block") 68 | destination_type = "SERVICE_CIDR_BLOCK" 69 | protocol = local.tcp_protocol_number 70 | stateless = false 71 | 72 | tcp_options { 73 | max = local.https_port_number 74 | min = local.https_port_number 75 | } 76 | } 77 | egress_security_rules { 78 | description = "ICMP Access from Kubernetes Control Plane" 79 | destination = lookup(var.network_cidrs, "ALL-CIDR") 80 | destination_type = "CIDR_BLOCK" 81 | protocol = local.icmp_protocol_number 82 | stateless = false 83 | 84 | icmp_options { 85 | type = "3" 86 | code = "4" 87 | } 88 | } 89 | egress_security_rules { 90 | description = "Access to Kubernetes API Endpoint" 91 | destination = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 92 | destination_type = "CIDR_BLOCK" 93 | protocol = local.tcp_protocol_number 94 | stateless = false 95 | 96 | tcp_options { 97 | max = local.k8s_api_endpoint_port_number 98 | min = local.k8s_api_endpoint_port_number 99 | } 100 | } 101 | egress_security_rules { 102 | description = "Kubernetes worker to control plane communication" 103 | destination = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 104 | destination_type = "CIDR_BLOCK" 105 | protocol = local.tcp_protocol_number 106 | stateless = false 107 | 108 | tcp_options { 109 | max = local.k8s_worker_to_control_plane_port_number 110 | min = local.k8s_worker_to_control_plane_port_number 111 | } 112 | } 113 | egress_security_rules { 114 | description = "Path discovery" 115 | destination = lookup(var.network_cidrs, "ENDPOINT-SUBNET-REGIONAL-CIDR") 116 | destination_type = "CIDR_BLOCK" 117 | protocol = local.icmp_protocol_number 118 | stateless = false 119 | 120 | icmp_options { 121 | type = "3" 122 | code = "4" 123 | } 124 | } 125 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 126 | 127 | count = var.create_new_oke_cluster ? 1 : 0 128 | } 129 | 130 | resource "oci_core_security_list" "oke_lb_security_list" { 131 | compartment_id = local.oke_compartment_id 132 | display_name = "oke-lb-seclist-${random_string.deploy_id.result}" 133 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 134 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 135 | 136 | count = var.create_new_oke_cluster ? 1 : 0 137 | } 138 | 139 | resource "oci_core_security_list" "oke_endpoint_security_list" { 140 | compartment_id = local.oke_compartment_id 141 | display_name = "oke-k8s-api-endpoint-seclist-${random_string.deploy_id.result}" 142 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 143 | 144 | # Ingresses 145 | 146 | ingress_security_rules { 147 | description = "External access to Kubernetes API endpoint" 148 | source = lookup(var.network_cidrs, (var.cluster_endpoint_visibility == "Private") ? "VCN-CIDR" : "ALL-CIDR") 149 | source_type = "CIDR_BLOCK" 150 | protocol = local.tcp_protocol_number 151 | stateless = false 152 | 153 | tcp_options { 154 | max = local.k8s_api_endpoint_port_number 155 | min = local.k8s_api_endpoint_port_number 156 | } 157 | } 158 | ingress_security_rules { 159 | description = "Kubernetes worker to Kubernetes API endpoint communication" 160 | source = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 161 | source_type = "CIDR_BLOCK" 162 | protocol = local.tcp_protocol_number 163 | stateless = false 164 | 165 | tcp_options { 166 | max = local.k8s_api_endpoint_port_number 167 | min = local.k8s_api_endpoint_port_number 168 | } 169 | } 170 | ingress_security_rules { 171 | description = "Kubernetes worker to control plane communication" 172 | source = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 173 | source_type = "CIDR_BLOCK" 174 | protocol = local.tcp_protocol_number 175 | stateless = false 176 | 177 | tcp_options { 178 | max = local.k8s_worker_to_control_plane_port_number 179 | min = local.k8s_worker_to_control_plane_port_number 180 | } 181 | } 182 | ingress_security_rules { 183 | description = "Path discovery" 184 | source = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 185 | source_type = "CIDR_BLOCK" 186 | protocol = local.icmp_protocol_number 187 | stateless = false 188 | 189 | icmp_options { 190 | type = "3" 191 | code = "4" 192 | } 193 | } 194 | 195 | # Egresses 196 | 197 | egress_security_rules { 198 | description = "Allow Kubernetes Control Plane to communicate with OKE" 199 | destination = lookup(data.oci_core_services.all_services.services[0], "cidr_block") 200 | destination_type = "SERVICE_CIDR_BLOCK" 201 | protocol = local.tcp_protocol_number 202 | stateless = false 203 | 204 | tcp_options { 205 | max = local.https_port_number 206 | min = local.https_port_number 207 | } 208 | } 209 | egress_security_rules { 210 | description = "All traffic to worker nodes" 211 | destination = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 212 | destination_type = "CIDR_BLOCK" 213 | protocol = local.tcp_protocol_number 214 | stateless = false 215 | } 216 | egress_security_rules { 217 | description = "Path discovery" 218 | destination = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 219 | destination_type = "CIDR_BLOCK" 220 | protocol = local.icmp_protocol_number 221 | stateless = false 222 | 223 | icmp_options { 224 | type = "3" 225 | code = "4" 226 | } 227 | } 228 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 229 | 230 | count = var.create_new_oke_cluster ? 1 : 0 231 | 232 | } 233 | 234 | locals { 235 | http_port_number = "80" 236 | https_port_number = "443" 237 | k8s_api_endpoint_port_number = "6443" 238 | k8s_worker_to_control_plane_port_number = "12250" 239 | ssh_port_number = "22" 240 | tcp_protocol_number = "6" 241 | icmp_protocol_number = "1" 242 | all_protocols = "all" 243 | } 244 | -------------------------------------------------------------------------------- /oke-variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | # OKE Variables 6 | ## OKE Cluster Details 7 | 8 | variable "create_new_oke_cluster" { 9 | default = true 10 | description = "Creates a new OKE cluster, node pool and network resources" 11 | } 12 | variable "existent_oke_cluster_id" { 13 | default = "" 14 | description = "Using existent OKE Cluster. Only the application and services will be provisioned. If select cluster autoscaler feature, you need to get the node pool id and enter when required" 15 | } 16 | variable "create_new_compartment_for_oke" { 17 | default = false 18 | description = "Creates new compartment for OKE Nodes and OCI Services deployed. NOTE: The creation of the compartment increases the deployment time by at least 3 minutes, and can increase by 15 minutes when destroying" 19 | } 20 | variable "oke_compartment_description" { 21 | default = "Compartment for OKE, Nodes and Services" 22 | } 23 | variable "cluster_options_add_ons_is_kubernetes_dashboard_enabled" { 24 | default = false 25 | } 26 | variable "cluster_options_admission_controller_options_is_pod_security_policy_enabled" { 27 | description = "If true: The pod security policy admission controller will use pod security policies to restrict the pods accepted into the cluster." 28 | default = false 29 | } 30 | 31 | ## OKE Visibility (Workers and Endpoint) 32 | 33 | variable "cluster_workers_visibility" { 34 | default = "Private" 35 | description = "The Kubernetes worker nodes that are created will be hosted in public or private subnet(s)" 36 | 37 | validation { 38 | condition = var.cluster_workers_visibility == "Private" || var.cluster_workers_visibility == "Public" 39 | error_message = "Sorry, but cluster visibility can only be Private or Public." 40 | } 41 | } 42 | 43 | variable "cluster_endpoint_visibility" { 44 | default = "Public" 45 | description = "The Kubernetes cluster that is created will be hosted on a public subnet with a public IP address auto-assigned or on a private subnet. If Private, additional configuration will be necessary to run kubectl commands" 46 | 47 | validation { 48 | condition = var.cluster_endpoint_visibility == "Private" || var.cluster_endpoint_visibility == "Public" 49 | error_message = "Sorry, but cluster endpoint visibility can only be Private or Public." 50 | } 51 | } 52 | 53 | ## OKE Encryption details 54 | variable "use_encryption_from_oci_vault" { 55 | default = false 56 | description = "By default, Oracle manages the keys that encrypts Kubernetes Secrets at Rest in Etcd, but you can choose a key from a vault that you have access to, if you want greater control over the key's lifecycle and how it's used" 57 | } 58 | variable "create_new_encryption_key" { 59 | default = false 60 | description = "Creates new vault and key on OCI Vault/Key Management/KMS and assign to boot volume of the worker nodes" 61 | } 62 | variable "existent_encryption_key_id" { 63 | default = "" 64 | description = "Use an existent master encryption key to encrypt boot volume and object storage bucket. NOTE: If the key resides in a different compartment or in a different tenancy, make sure you have the proper policies to access, or the provision of the worker nodes will fail" 65 | } 66 | variable "create_vault_policies_for_group" { 67 | default = false 68 | description = "Creates policies to allow the user applying the stack to manage vault and keys. If you are on the Administrators group or already have the policies for a compartment, this policy is not needed. If you do not have access to allow the policy, ask your administrator to include it for you" 69 | } 70 | variable "user_admin_group_for_vault_policy" { 71 | default = "Administrators" 72 | description = "User Identity Group to allow manage vault and keys. The user running the Terraform scripts or Applying the ORM Stack need to be on this group" 73 | } 74 | 75 | # ## OKE Autoscaler 76 | # variable "cluster_autoscaler_enabled" { 77 | # default = true 78 | # description = "Enables OKE cluster autoscaler. Node pools will auto scale based on the resources usage" 79 | # } 80 | # variable "cluster_autoscaler_min_nodes" { 81 | # default = 3 82 | # description = "Minimum number of nodes on the node pool to be scheduled by the Kubernetes" 83 | # } 84 | # variable "cluster_autoscaler_max_nodes" { 85 | # default = 10 86 | # description = "Maximum number of nodes on the node pool to be scheduled by the Kubernetes" 87 | # } 88 | # variable "existent_oke_nodepool_id_for_autoscaler" { 89 | # default = "" 90 | # description = "Nodepool Id of the existent OKE to use with Cluster Autoscaler" 91 | # } 92 | 93 | ## OKE Node Pool Details 94 | variable "node_pool_name" { 95 | default = "pool1" 96 | description = "Name of the node pool" 97 | } 98 | variable "k8s_version" { 99 | default = "Latest" 100 | description = "Kubernetes version installed on your master and worker nodes" 101 | } 102 | variable "num_pool_workers" { 103 | default = 3 104 | description = "The number of worker nodes in the node pool. If select Cluster Autoscaler, will assume the minimum number of nodes configured" 105 | } 106 | variable "node_pool_shape" { 107 | default = "VM.Standard.E3.Flex" 108 | description = "A shape is a template that determines the number of OCPUs, amount of memory, and other resources allocated to a newly created instance for the Worker Node" 109 | } 110 | variable "node_pool_node_shape_config_ocpus" { 111 | default = "1" # Only used if flex shape is selected 112 | description = "You can customize the number of OCPUs to a flexible shape" 113 | } 114 | variable "node_pool_node_shape_config_memory_in_gbs" { 115 | default = "16" # Only used if flex shape is selected 116 | description = "You can customize the amount of memory allocated to a flexible shape" 117 | } 118 | variable "node_pool_boot_volume_size_in_gbs" { 119 | default = "60" 120 | description = "Specify a custom boot volume size (in GB)" 121 | } 122 | variable "image_operating_system" { 123 | default = "Oracle Linux" 124 | description = "The OS/image installed on all nodes in the node pool." 125 | } 126 | variable "image_operating_system_version" { 127 | default = "7.9" 128 | description = "The OS/image version installed on all nodes in the node pool." 129 | } 130 | variable "generate_public_ssh_key" { 131 | default = true 132 | } 133 | variable "public_ssh_key" { 134 | default = "" 135 | description = "In order to access your private nodes with a public SSH key you will need to set up a bastion host (a.k.a. jump box). If using public nodes, bastion is not needed. Left blank to not import keys." 136 | } 137 | 138 | # Network Details 139 | ## CIDRs 140 | variable "network_cidrs" { 141 | type = map(string) 142 | 143 | default = { 144 | VCN-CIDR = "10.20.0.0/16" 145 | SUBNET-REGIONAL-CIDR = "10.20.10.0/24" 146 | LB-SUBNET-REGIONAL-CIDR = "10.20.20.0/24" 147 | ENDPOINT-SUBNET-REGIONAL-CIDR = "10.20.0.0/28" 148 | ALL-CIDR = "0.0.0.0/0" 149 | PODS-CIDR = "10.244.0.0/16" 150 | KUBERNETES-SERVICE-CIDR = "10.96.0.0/16" 151 | } 152 | } 153 | 154 | 155 | # Create Dynamic Group and Policies 156 | variable "create_dynamic_group_for_nodes_in_compartment" { 157 | default = true 158 | description = "Creates dynamic group of Nodes in the compartment. Note: You need to have proper rights on the Tenancy. If you only have rights in a compartment, uncheck and ask you administrator to create the Dynamic Group for you" 159 | } 160 | variable "existent_dynamic_group_for_nodes_in_compartment" { 161 | default = "" 162 | description = "Enter previous created Dynamic Group for the policies" 163 | } 164 | variable "create_compartment_policies" { 165 | default = true 166 | description = "Creates policies that will reside on the compartment. e.g.: Policies to support Cluster Autoscaler, OCI Logging datasource on Grafana" 167 | } 168 | variable "create_tenancy_policies" { 169 | default = true 170 | description = "Creates policies that need to reside on the tenancy. e.g.: Policies to support OCI Metrics datasource on Grafana" 171 | } 172 | 173 | # ORM Schema visual control variables 174 | variable "show_advanced" { 175 | default = false 176 | } 177 | 178 | # Dictionary Locals 179 | locals { 180 | compute_flexible_shapes = [ 181 | "VM.Standard.E3.Flex", 182 | "VM.Standard.E4.Flex", 183 | "VM.Standard.A1.Flex" 184 | ] 185 | } -------------------------------------------------------------------------------- /oke.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | 5 | module "oci-oke" { 6 | count = var.create_new_oke_cluster ? 1 : 0 7 | source = "github.com/oracle-devrel/terraform-oci-arch-oke" 8 | tenancy_ocid = var.tenancy_ocid 9 | compartment_ocid = local.oke_compartment_id 10 | oke_cluster_name = "${var.app_name} (${random_string.deploy_id.result})" 11 | services_cidr = lookup(var.network_cidrs, "KUBERNETES-SERVICE-CIDR") 12 | pods_cidr = lookup(var.network_cidrs, "PODS-CIDR") 13 | cluster_options_add_ons_is_kubernetes_dashboard_enabled = var.cluster_options_add_ons_is_kubernetes_dashboard_enabled 14 | cluster_options_add_ons_is_tiller_enabled = false 15 | cluster_options_admission_controller_options_is_pod_security_policy_enabled = var.cluster_options_admission_controller_options_is_pod_security_policy_enabled 16 | pool_name = var.node_pool_name 17 | node_shape = var.node_pool_shape 18 | node_ocpus = var.node_pool_node_shape_config_ocpus 19 | node_memory = var.node_pool_node_shape_config_memory_in_gbs 20 | node_count = var.num_pool_workers 21 | node_pool_boot_volume_size_in_gbs = var.node_pool_boot_volume_size_in_gbs 22 | k8s_version = (var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version 23 | use_existing_vcn = true 24 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 25 | is_api_endpoint_subnet_public = (var.cluster_endpoint_visibility == "Private") ? false : true 26 | api_endpoint_subnet_id = oci_core_subnet.oke_k8s_endpoint_subnet[0].id 27 | api_endpoint_nsg_ids = [] 28 | is_lb_subnet_public = true 29 | lb_subnet_id = oci_core_subnet.oke_lb_subnet[0].id 30 | is_nodepool_subnet_public = false 31 | nodepool_subnet_id = oci_core_subnet.oke_nodes_subnet[0].id 32 | ssh_public_key = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.public_key_openssh : var.public_ssh_key 33 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 34 | } 35 | 36 | 37 | 38 | resource "oci_identity_compartment" "oke_compartment" { 39 | compartment_id = var.compartment_ocid 40 | name = "oke-compartment-${random_string.deploy_id.result}" 41 | description = "${var.oke_compartment_description} (Deployment ${random_string.deploy_id.result})" 42 | enable_delete = true 43 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 44 | 45 | count = var.create_new_compartment_for_oke ? 1 : 0 46 | } 47 | locals { 48 | #oke_compartment_id = var.create_new_compartment_for_oke ? oci_identity_compartment.oke_compartment.0.id : var.compartment_id 49 | oke_compartment_id = var.compartment_ocid 50 | } 51 | 52 | # Local kubeconfig for when using Terraform locally. Not used by Oracle Resource Manager 53 | resource "local_file" "kubeconfig" { 54 | content = data.oci_containerengine_cluster_kube_config.oke_cluster_kube_config.content 55 | filename = "generated/kubeconfig" 56 | } 57 | 58 | # Generate ssh keys to access Worker Nodes, if generate_public_ssh_key=true, applies to the pool 59 | resource "tls_private_key" "oke_worker_node_ssh_key" { 60 | algorithm = "RSA" 61 | rsa_bits = 2048 62 | } 63 | 64 | # Get OKE options 65 | locals { 66 | cluster_k8s_latest_version = reverse(sort(data.oci_containerengine_cluster_option.oke.kubernetes_versions))[0] 67 | node_pool_k8s_latest_version = reverse(sort(data.oci_containerengine_node_pool_option.oke.kubernetes_versions))[0] 68 | } 69 | 70 | # Checks if is using Flexible Compute Shapes 71 | locals { 72 | is_flexible_node_shape = contains(local.compute_flexible_shapes, var.node_pool_shape) 73 | } 74 | 75 | 76 | /* 77 | resource "oci_containerengine_cluster" "oke_cluster" { 78 | compartment_id = local.oke_compartment_id 79 | kubernetes_version = (var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version 80 | name = "OKE-DevOps-Cluster-(${random_string.deploy_id.result})" 81 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 82 | 83 | endpoint_config { 84 | is_public_ip_enabled = (var.cluster_endpoint_visibility == "Private") ? false : true 85 | subnet_id = oci_core_subnet.oke_k8s_endpoint_subnet[0].id 86 | } 87 | options { 88 | service_lb_subnet_ids = [oci_core_subnet.oke_lb_subnet[0].id] 89 | add_ons { 90 | is_kubernetes_dashboard_enabled = var.cluster_options_add_ons_is_kubernetes_dashboard_enabled 91 | is_tiller_enabled = false # Default is false, left here for reference 92 | } 93 | admission_controller_options { 94 | is_pod_security_policy_enabled = var.cluster_options_admission_controller_options_is_pod_security_policy_enabled 95 | } 96 | kubernetes_network_config { 97 | services_cidr = lookup(var.network_cidrs, "KUBERNETES-SERVICE-CIDR") 98 | pods_cidr = lookup(var.network_cidrs, "PODS-CIDR") 99 | } 100 | } 101 | # kms_key_id = var.use_encryption_from_oci_vault ? (var.create_new_encryption_key ? oci_kms_key.mushop_key[0].id : var.existent_encryption_key_id) : null 102 | 103 | count = var.create_new_oke_cluster ? 1 : 0 104 | } 105 | 106 | resource "oci_containerengine_node_pool" "oke_node_pool" { 107 | cluster_id = oci_containerengine_cluster.oke_cluster[0].id 108 | compartment_id = local.oke_compartment_id 109 | kubernetes_version = (var.k8s_version == "Latest") ? local.node_pool_k8s_latest_version : var.k8s_version 110 | name = var.node_pool_name 111 | node_shape = var.node_pool_shape 112 | ssh_public_key = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.public_key_openssh : var.public_ssh_key 113 | 114 | node_config_details { 115 | dynamic "placement_configs" { 116 | for_each = data.oci_identity_availability_domains.ADs.availability_domains 117 | 118 | content { 119 | availability_domain = placement_configs.value.name 120 | subnet_id = oci_core_subnet.oke_nodes_subnet[0].id 121 | } 122 | } 123 | #size = var.cluster_autoscaler_enabled ? var.cluster_autoscaler_min_nodes : var.num_pool_workers 124 | size = var.num_pool_workers 125 | } 126 | 127 | dynamic "node_shape_config" { 128 | for_each = local.is_flexible_node_shape ? [1] : [] 129 | content { 130 | ocpus = var.node_pool_node_shape_config_ocpus 131 | memory_in_gbs = var.node_pool_node_shape_config_memory_in_gbs 132 | } 133 | } 134 | 135 | node_source_details { 136 | source_type = "IMAGE" 137 | image_id = lookup(data.oci_core_images.node_pool_images.images[0], "id") 138 | boot_volume_size_in_gbs = var.node_pool_boot_volume_size_in_gbs 139 | } 140 | 141 | initial_node_labels { 142 | key = "name" 143 | value = var.node_pool_name 144 | } 145 | 146 | count = var.create_new_oke_cluster ? 1 : 0 147 | } 148 | 149 | */ 150 | -------------------------------------------------------------------------------- /orm/provider.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | terraform { 5 | required_version = ">= 1.0" 6 | required_providers { 7 | oci = { 8 | source = "oracle/oci" 9 | } 10 | } 11 | } 12 | 13 | provider "oci" { 14 | tenancy_ocid = var.tenancy_ocid 15 | region = var.region 16 | 17 | #user_ocid = var.user_ocid 18 | #fingerprint = var.fingerprint 19 | #private_key_path = var.private_key_path 20 | } 21 | 22 | provider "oci" { 23 | alias = "home_region" 24 | tenancy_ocid = var.tenancy_ocid 25 | region = lookup(data.oci_identity_regions.home_region.regions[0], "name") 26 | 27 | #user_ocid = var.user_ocid 28 | #fingerprint = var.fingerprint 29 | #private_key_path = var.private_key_path 30 | } 31 | 32 | provider "oci" { 33 | alias = "current_region" 34 | tenancy_ocid = var.tenancy_ocid 35 | region = var.region 36 | 37 | #user_ocid = var.user_ocid 38 | #fingerprint = var.fingerprint 39 | #private_key_path = var.private_key_path 40 | } 41 | -------------------------------------------------------------------------------- /orm/variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | variable "tenancy_ocid" {} 5 | variable "compartment_ocid" {} 6 | # variable "user_ocid" {} 7 | # variable "fingerprint" {} 8 | # variable "private_key_path" {} 9 | variable "region" {} 10 | 11 | variable "app_name" { 12 | default = "DevOps" 13 | description = "Application name. Will be used as prefix to identify resources, such as OKE, VCN, DevOps, and others" 14 | } 15 | 16 | variable "oci_username" {} 17 | variable "oci_user_authtoken" {} 18 | 19 | variable "release" { 20 | description = "Reference Architecture Release (OCI Architecture Center)" 21 | default = "1.1.2" 22 | } 23 | 24 | variable "project_logging_config_retention_period_in_days" { 25 | default = 30 26 | } 27 | 28 | variable "project_description" { 29 | default = "DevOps CI/CD Sample Project" 30 | } 31 | 32 | 33 | variable "build_pipeline_description" { 34 | default = "build pipeline for Node.JS application" 35 | } 36 | 37 | variable "build_pipeline_display_name" { 38 | default = "NodeJS-build-pipeline" 39 | } 40 | 41 | variable "repository_name" { 42 | default = "nodejs" 43 | } 44 | 45 | variable "repository_default_branch" { 46 | default = "main" 47 | } 48 | 49 | variable "repository_description" { 50 | default = "nodejs sample application" 51 | } 52 | 53 | variable "git_repo" { 54 | default = "https://github.com/oracle-quickstart/oci-devops-node.git" 55 | } 56 | 57 | variable "git_repo_name" { 58 | default = "oci-devops-node" 59 | } 60 | 61 | variable "build_pipeline_stage_build_pipeline_stage_predecessor_collection_items_id" { 62 | default = "id" 63 | } 64 | 65 | variable "build_pipeline_stage_build_pipeline_stage_type" { 66 | default = "BUILD" 67 | } 68 | 69 | variable "build_pipeline_stage_deliver_artifact_stage_type" { 70 | default = "DELIVER_ARTIFACT" 71 | } 72 | 73 | variable "build_pipeline_stage_deploy_stage_type" { 74 | default = "TRIGGER_DEPLOYMENT_PIPELINE" 75 | } 76 | 77 | variable "build_pipeline_stage_build_source_collection_items_branch" { 78 | default = "main" 79 | } 80 | 81 | variable "build_pipeline_stage_build_source_collection_items_connection_type" { 82 | default = "DEVOPS_CODE_REPOSITORY" 83 | } 84 | 85 | variable "build_pipeline_stage_build_source_collection_items_name" { 86 | default = "node_express" 87 | } 88 | 89 | variable "build_pipeline_stage_build_spec_file" { 90 | default = "" 91 | } 92 | 93 | variable "build_pipeline_stage_deliver_artifact_collection_items_artifact_name" { 94 | default = "output01" 95 | } 96 | 97 | variable "build_pipeline_stage_display_name" { 98 | default = "nodejs-build-pipeline" 99 | } 100 | 101 | variable "build_pipeline_stage_description"{ 102 | default = "nodejs managed build stage" 103 | } 104 | 105 | variable "deliver_artifact_stage_display_name" { 106 | default = "deliver-artifact" 107 | } 108 | 109 | variable "deploy_stage_display_name" { 110 | default = "deploy-artifact" 111 | } 112 | 113 | variable "build_pipeline_stage_image" { 114 | default = "OL7_X86_64_STANDARD_10" 115 | } 116 | 117 | variable "build_pipeline_stage_wait_criteria_wait_duration" { 118 | default = "waitDuration" 119 | } 120 | 121 | variable "build_pipeline_stage_wait_criteria_wait_type" { 122 | default = "ABSOLUTE_WAIT" 123 | } 124 | 125 | variable "build_pipeline_stage_stage_execution_timeout_in_seconds" { 126 | default = 36000 127 | } 128 | 129 | /* 130 | variable "registry_display_name" { 131 | default = "node-express-getting-starter" 132 | } 133 | */ 134 | 135 | variable "container_repository_is_public" { 136 | default = true 137 | } 138 | 139 | variable "deploy_artifact_argument_substitution_mode" { 140 | default = "SUBSTITUTE_PLACEHOLDERS" 141 | } 142 | 143 | /* 144 | variable "deploy_artifact_display_name" { 145 | default = "node-express-getting-starter" 146 | } 147 | */ 148 | 149 | locals { 150 | ocir_docker_repository = join("", [lower(lookup(data.oci_identity_regions.current_region.regions[0], "key")), ".ocir.io"]) 151 | #ocir_docker_repository = join("", [lower(lookup(data.oci_identity_regions.home_region.regions[0], "key")), ".ocir.io"]) 152 | #ocir_namespace = lookup(data.oci_identity_tenancy.oci_tenancy, "name" ) 153 | ocir_namespace = lookup(data.oci_objectstorage_namespace.ns, "namespace") 154 | } 155 | 156 | #variable "ocir_region" { 157 | # default = "iad"} 158 | 159 | variable "deploy_artifact_deploy_artifact_source_deploy_artifact_source_type" { 160 | default = "OCIR" 161 | } 162 | 163 | variable "deploy_artifact_deploy_artifact_type" { 164 | default = "DOCKER_IMAGE" 165 | } 166 | 167 | variable "repository_repository_type" { 168 | default = "HOSTED" 169 | } 170 | 171 | variable "deploy_artifact_type" { 172 | default = "KUBERNETES_MANIFEST" 173 | } 174 | 175 | variable "deploy_pipeline_description" { 176 | default = "Devops CI/CD Pipleline demo for OKE" 177 | } 178 | 179 | variable "deploy_artifact_source_type" { 180 | default = "INLINE" 181 | } 182 | 183 | variable "deploy_pipeline_deploy_pipeline_parameters_items_default_value" { 184 | default = "example" 185 | } 186 | 187 | variable "deploy_pipeline_deploy_pipeline_parameters_items_description" { 188 | default = "exampleapp" 189 | } 190 | 191 | variable "deploy_pipeline_deploy_pipeline_parameters_items_name" { 192 | default = "namespace" 193 | } 194 | 195 | variable "deploy_stage_deploy_stage_type" { 196 | default = "OKE_DEPLOYMENT" 197 | } 198 | 199 | variable "deploy_stage_description" { 200 | default = "ci/cd deployment to OKE" 201 | } 202 | 203 | variable "execute_deployment" { 204 | default = true 205 | } 206 | 207 | variable "build_pipeline_stage_is_pass_all_parameters_enabled" { 208 | default = true 209 | } 210 | 211 | -------------------------------------------------------------------------------- /policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "oci_identity_dynamic_group" "devopsgroup1" { 5 | provider = oci.home_region 6 | name = "devopsdyngroup-${random_id.tag.hex}" 7 | description = "DevOps deploy pipeline dynamic group" 8 | compartment_id = var.tenancy_ocid 9 | matching_rule = "ALL {resource.type = 'devopsdeploypipeline', resource.compartment.id = '${var.compartment_ocid}'}" 10 | } 11 | 12 | resource "oci_identity_dynamic_group" "devopsgroup2" { 13 | provider = oci.home_region 14 | name = "CodeReposDynamicGroup-${random_id.tag.hex}" 15 | description = "DevOps code repository dynamic group" 16 | compartment_id = var.tenancy_ocid 17 | matching_rule = "ALL {resource.type = 'devopsrepository'}" 18 | } 19 | 20 | 21 | resource "oci_identity_dynamic_group" "devopsgroup3" { 22 | provider = oci.home_region 23 | name = "MyDynamicGroup-${random_id.tag.hex}" 24 | description = "DevOps repository build pipeline dynamic group" 25 | compartment_id = var.tenancy_ocid 26 | matching_rule = "ALL {resource.type = 'devopsbuildpipeline'}" 27 | } 28 | 29 | 30 | resource "oci_identity_policy" "devopspolicy" { 31 | provider = oci.home_region 32 | name = "devops-policies-${random_id.tag.hex}" 33 | description = "policy created for devops" 34 | compartment_id = var.compartment_ocid 35 | 36 | statements = [ 37 | "Allow group Administrators to manage devops-family in compartment id ${var.compartment_ocid}", 38 | "Allow group Administrators to manage all-artifacts in compartment id ${var.compartment_ocid}", 39 | "Allow dynamic-group ${oci_identity_dynamic_group.devopsgroup1.name} to manage all-resources in compartment id ${var.compartment_ocid}", 40 | ] 41 | } 42 | 43 | resource "oci_identity_policy" "devopsrootpolicy" { 44 | provider = oci.home_region 45 | name = "devops-root-policies-${random_id.tag.hex}" 46 | description = "policy created for root compartment" 47 | compartment_id = var.tenancy_ocid 48 | 49 | statements = [ 50 | "Allow dynamic-group ${oci_identity_dynamic_group.devopsgroup2.name} to manage all-resources in tenancy", 51 | "Allow dynamic-group ${oci_identity_dynamic_group.devopsgroup3.name} to manage all-resources in tenancy", 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /provider.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | terraform { 5 | required_version = ">= 1.0" 6 | required_providers { 7 | oci = { 8 | source = "oracle/oci" 9 | } 10 | } 11 | } 12 | 13 | provider "oci" { 14 | tenancy_ocid = var.tenancy_ocid 15 | region = var.region 16 | 17 | user_ocid = var.user_ocid 18 | fingerprint = var.fingerprint 19 | private_key_path = var.private_key_path 20 | } 21 | 22 | provider "oci" { 23 | alias = "home_region" 24 | tenancy_ocid = var.tenancy_ocid 25 | region = lookup(data.oci_identity_regions.home_region.regions[0], "name") 26 | 27 | user_ocid = var.user_ocid 28 | fingerprint = var.fingerprint 29 | private_key_path = var.private_key_path 30 | } 31 | 32 | provider "oci" { 33 | alias = "current_region" 34 | tenancy_ocid = var.tenancy_ocid 35 | region = var.region 36 | 37 | user_ocid = var.user_ocid 38 | fingerprint = var.fingerprint 39 | private_key_path = var.private_key_path 40 | } 41 | -------------------------------------------------------------------------------- /release_files.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "action": "create_zip", 4 | "file_name": "terraform-oci-arch-ci-cd-devops-stack-latest.zip", 5 | "files": [ 6 | { 7 | "src_pattern": "*.tf", 8 | "dst_path": ".", 9 | "exclude": [ 10 | "provider.tf", 11 | "variables.tf" 12 | ] 13 | }, 14 | { 15 | "src": "LICENSE" 16 | }, 17 | { 18 | "src": "schema.yaml", 19 | "dst": "schema.yaml" 20 | }, 21 | { 22 | "src": "orm/variables.tf", 23 | "dst": "variables.tf" 24 | }, 25 | { 26 | "src": "orm/provider.tf", 27 | "dst": "provider.tf" 28 | }, 29 | { 30 | "src_pattern": "manifest/*" 31 | } 32 | ] 33 | }, 34 | { 35 | "action": "upload_file", 36 | "file_name": "terraform-oci-arch-ci-cd-devops-stack-latest.zip" 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 3 | "version": 2, 4 | "axioms": {}, 5 | "rules": { 6 | "readme-file-exists" : { 7 | "level": "error", 8 | "rule": { 9 | "type": "file-existence", 10 | "options": { 11 | "globsAny": ["README*"] 12 | } 13 | } 14 | }, 15 | "disclaimer-present" : { 16 | "level": "error", 17 | "rule": { 18 | "type": "file-contents", 19 | "options": { 20 | "globsAll": ["README*"], 21 | "noCase": true, 22 | "fail-on-non-existent": true, 23 | "content": "ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND" 24 | } 25 | } 26 | }, 27 | "license-file-exists" : { 28 | "level": "error", 29 | "rule": { 30 | "type": "file-existence", 31 | "options": { 32 | "globsAny": ["LICENSE*"] 33 | } 34 | } 35 | }, 36 | "copyright-notice-present" : { 37 | "level": "warning", 38 | "rule": { 39 | "type": "file-starts-with", 40 | "options": { 41 | "globsAll": ["**/*"], 42 | "skip-binary-files": true, 43 | "skip-paths-matching": { 44 | "extensions": ["yaml","yml","md","json","xml","tpl","ipynb","pickle","joblib","properties"], 45 | "patterns": ["\\.github"], 46 | "flags": "" 47 | }, 48 | "lineCount": 2, 49 | "patterns": [ 50 | "Copyright \\([cC]\\) [12][90]\\d\\d(\\-[12][90]\\d\\d)? Oracle and/or its affiliates\\." 51 | ], 52 | "succeed-on-non-exist": true 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /schema.yaml: -------------------------------------------------------------------------------- 1 | title: "Build a CI/CD pipelines by using OCI DevOps services." 2 | stackDescription: "Build a continuous integration and deployment pipeline by using Oracle Cloud Infrastructure DevOps services." 3 | description: "Build a continuous integration and deployment pipeline by using Oracle Cloud Infrastructure DevOps services." 4 | schemaVersion: 1.1.0 5 | version: "20190404" 6 | locale: "en" 7 | 8 | ################# 9 | # Variable Groups 10 | ################# 11 | variableGroups: 12 | - title: General Configuration 13 | visible: false 14 | variables: 15 | - tenancy_ocid 16 | - compartment_ocid 17 | - region 18 | - oke_compartment_description 19 | - network_cidrs 20 | - node_pool_boot_volume_size_in_gbs 21 | - deploy_pipeline_deploy_pipeline_parameters_items_default_value 22 | - deploy_pipeline_deploy_pipeline_parameters_items_description 23 | - deploy_pipeline_deploy_pipeline_parameters_items_name 24 | - build_pipeline_stage_build_pipeline_stage_predecessor_collection_items_id 25 | - build_pipeline_stage_build_pipeline_stage_type 26 | - build_pipeline_stage_description 27 | - build_pipeline_stage_deliver_artifact_stage_type 28 | - build_pipeline_stage_deploy_stage_type 29 | - build_pipeline_stage_build_source_collection_items_branch 30 | - build_pipeline_stage_build_source_collection_items_connection_type 31 | - build_pipeline_stage_build_source_collection_items_name 32 | - build_pipeline_stage_build_spec_file 33 | - build_pipeline_stage_deliver_artifact_collection_items_artifact_name 34 | - build_pipeline_stage_image 35 | - build_pipeline_stage_wait_criteria_wait_duration 36 | - build_pipeline_stage_wait_criteria_wait_type 37 | - deploy_artifact_argument_substitution_mode 38 | - deploy_artifact_deploy_artifact_source_deploy_artifact_source_type 39 | - deploy_artifact_deploy_artifact_type 40 | - repository_repository_type 41 | - deploy_artifact_type 42 | - deploy_artifact_source_type 43 | - deploy_stage_deploy_stage_type 44 | - deploy_artifact_source_type 45 | - deploy_stage_deploy_stage_type 46 | - execute_deployment 47 | - release 48 | 49 | 50 | - title: Required Configuration 51 | visible: true 52 | variables: 53 | - oci_username 54 | - oci_user_authtoken 55 | - show_advanced 56 | 57 | - title: DevOps Project Configuration 58 | visible: true 59 | variables: 60 | - compartment_id 61 | - app_name 62 | - project_description 63 | - project_logging_config_retention_period_in_days 64 | 65 | - title: DevOps Build Pipeline Configuration 66 | visible: true 67 | variables: 68 | - build_pipeline_description 69 | - build_pipeline_display_name 70 | 71 | - title: DevOps Build Pipeline - Build Stage Configuration 72 | visible: true 73 | variables: 74 | - repository_name 75 | - repository_default_branch 76 | - repository_description 77 | - git_repo 78 | - git_repo_name 79 | - build_pipeline_stage_build_source_collection_items_name 80 | - build_pipeline_stage_display_name 81 | - build_pipeline_stage_is_pass_all_parameters_enabled 82 | - build_pipeline_stage_stage_execution_timeout_in_seconds 83 | 84 | - title: DevOps Build Pipeline - Deliver Stage Configuration 85 | visible: true 86 | variables: 87 | - deliver_artifact_stage_display_name 88 | - registry_display_name 89 | - container_repository_is_public 90 | 91 | - title: DevOps Build Pipeline - Deploy Stage Configuration 92 | visible: true 93 | variables: 94 | - deploy_stage_display_name 95 | - deploy_stage_description 96 | - deploy_pipeline_description 97 | - deploy_artifact_display_name 98 | 99 | - title: Encryption Settings 100 | description: Policy setting for the stack deployment 101 | visible: true 102 | variables: 103 | - use_encryption_from_oci_vault 104 | - create_new_encryption_key 105 | - existent_encryption_key_id 106 | - create_vault_policies_for_group 107 | - user_admin_group_for_vault_policy 108 | 109 | - title: OKE Cluster Configuration 110 | visible: true 111 | variables: 112 | - create_new_oke_cluster 113 | - existent_oke_cluster_id 114 | - create_new_compartment_for_oke 115 | - oke_compartment_description 116 | - cluster_options_add_ons_is_kubernetes_dashboard_enabled 117 | - cluster_options_admission_controller_options_is_pod_security_policy_enabled 118 | - cluster_workers_visibility 119 | - cluster_endpoint_visibility 120 | - k8s_version 121 | 122 | - title: OKE Worker Nodes Configuration 123 | visible: true 124 | variables: 125 | - generate_public_ssh_key 126 | - public_ssh_key 127 | - num_pool_workers 128 | - node_pool_name 129 | - node_pool_shape 130 | - node_pool_node_shape_config_ocpus 131 | - node_pool_node_shape_config_memory_in_gbs 132 | - image_operating_system 133 | - image_operating_system_version 134 | - create_dynamic_group_for_nodes_in_compartment 135 | - existent_dynamic_group_for_nodes_in_compartment 136 | - create_compartment_policies 137 | - create_tenancy_policies 138 | 139 | ################# 140 | # Output Groups 141 | ################# 142 | 143 | 144 | ###################### 145 | # Variable Definitions 146 | ###################### 147 | 148 | variables: 149 | 150 | # Required 151 | 152 | oci_username: 153 | type: string 154 | required: true 155 | visibile: true 156 | title: "OCI username" 157 | description: "For a federated user (single sign-on with an identity provider), enter the username in the following format: TenancyName/Federation/UserName. For example, if you use OCI's identity provider, your login would be, Acme/oracleidentitycloudservice/alice.jones@acme.com. If you are using OCI's direct sign-in, enter the username in the following format: TenancyName/YourUserName. For example, Acme/alice_jones. Your password is the auth token you created previously." 158 | 159 | oci_user_authtoken: 160 | type: password 161 | required: true 162 | visibile: true 163 | title: "OCI user auth token" 164 | description: "You can get the auth token from your Profile menu -> click User Settings -> On left side click *Auth Tokens -> Generate Token" 165 | 166 | show_advanced: 167 | type: boolean 168 | title: "Show advanced options?" 169 | description: "Shows advanced options." 170 | visible: true 171 | default: false 172 | 173 | compartment_id: 174 | type: oci:identity:compartment:id 175 | title: "Compartment" 176 | description: "The compartment in which to create resources" 177 | required: true 178 | 179 | app_name: 180 | type: string 181 | title: "Project Name" 182 | required: true 183 | 184 | project_logging_config_retention_period_in_days: 185 | type: string 186 | title: "Project Logs retention period" 187 | description: "Days to retain logs from the Project." 188 | default: 30 189 | required: true 190 | visible: 191 | and: 192 | - show_advanced 193 | 194 | create_new_oke_cluster: 195 | type: boolean 196 | title: "Create new OKE cluster?" 197 | required: false 198 | 199 | existent_oke_cluster_id: 200 | type: string 201 | required: false 202 | visible: 203 | not: 204 | - create_new_oke_cluster 205 | title: "Use existing OKE cluster OCID" 206 | 207 | create_new_compartment_for_oke: 208 | type: boolean 209 | required: false 210 | visible: 211 | and: 212 | - create_new_oke_cluster 213 | title: "Create new compartment for OKE" 214 | 215 | oke_compartment_description: 216 | type: string 217 | required: false 218 | visible: 219 | and: 220 | - create_new_oke_cluster 221 | title: "OKE new compartment description" 222 | 223 | cluster_options_add_ons_is_kubernetes_dashboard_enabled: 224 | type: boolean 225 | required: false 226 | visible: 227 | and: 228 | - create_new_oke_cluster 229 | title: "OKE Cluster Add-ons: Enabled Kubernetes Dashboard?" 230 | 231 | cluster_options_admission_controller_options_is_pod_security_policy_enabled: 232 | type: boolean 233 | required: false 234 | visible: 235 | and: 236 | - create_new_oke_cluster 237 | title: "OKE Cluster Add-ons: Admission Controler options - Enabled POD Security Policy?" 238 | 239 | cluster_workers_visibility: 240 | type: enum 241 | required: false 242 | visible: 243 | and: 244 | - create_new_oke_cluster 245 | title: "Choose OKE Worker Nodes visibility type" 246 | enum: 247 | - "Private" 248 | - "Public" 249 | 250 | cluster_endpoint_visibility: 251 | type: enum 252 | required: false 253 | visible: 254 | and: 255 | - create_new_oke_cluster 256 | title: "Choose OKE API Endpoint visibility type" 257 | enum: 258 | - "Private" 259 | - "Public" 260 | 261 | use_encryption_from_oci_vault: 262 | type: boolean 263 | required: false 264 | title: "Encrypt using Customer-Managed Keys instead of Oracle Managed Encryption" 265 | visible: 266 | and: 267 | - create_new_oke_cluster 268 | - show_advanced 269 | 270 | create_new_encryption_key: 271 | type: boolean 272 | required: false 273 | visible: 274 | and: 275 | - create_new_oke_cluster 276 | - show_advanced 277 | - use_encryption_from_oci_vault 278 | title: "Create New Encryption Key?" 279 | 280 | existent_encryption_key_id: 281 | type: string 282 | title: "Existent Encryption Key OCID" 283 | required: false 284 | visible: 285 | and: 286 | - and: 287 | - create_new_oke_cluster 288 | - show_advanced 289 | - use_encryption_from_oci_vault 290 | - not: 291 | - create_new_encryption_key 292 | 293 | create_vault_policies_for_group: 294 | type: boolean 295 | title: "Create policies for the user group to manage vault and keys" 296 | visible: 297 | and: 298 | - create_new_oke_cluster 299 | - show_advanced 300 | - use_encryption_from_oci_vault 301 | - create_new_encryption_key 302 | 303 | user_admin_group_for_vault_policy: 304 | type: string 305 | title: "Specify your group to include the policy" 306 | visible: 307 | and: 308 | - create_new_oke_cluster 309 | - show_advanced 310 | - use_encryption_from_oci_vault 311 | - create_new_encryption_key 312 | - create_vault_policies_for_group 313 | 314 | k8s_version: 315 | type: string 316 | title: "Kubernetes Version" 317 | required: false 318 | description: If other than 'Latest', type the version number with a leading 'v', e.g. v1.23.4 319 | visible: 320 | and: 321 | - create_new_oke_cluster 322 | - show_advanced 323 | 324 | generate_public_ssh_key: 325 | type: boolean 326 | title: "Auto generate public ssh key?" 327 | required: true 328 | visible: 329 | and: 330 | - create_new_oke_cluster 331 | - show_advanced 332 | 333 | public_ssh_key: 334 | type: oci:core:ssh:publickey 335 | title: "Import your own SSH public key" 336 | additionalProps: 337 | allowMultiple: true 338 | required: false 339 | pattern: "((^(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+\/]+[=]{0,3})( [^,]*)?)(,((ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+\/]+[=]{0,3})( [^,]*)?)*$" 340 | visible: 341 | and: 342 | - and: 343 | - create_new_oke_cluster 344 | - show_advanced 345 | - not: 346 | - generate_public_ssh_key 347 | 348 | num_pool_workers: 349 | type: integer 350 | title: "Number of Worker Nodes" 351 | minimum: 1 352 | maximum: 1000 353 | required: true 354 | visible: 355 | and: 356 | - create_new_oke_cluster 357 | 358 | node_pool_name: 359 | type: string 360 | title: "Node Pool Name" 361 | required: false 362 | visible: 363 | and: 364 | - create_new_oke_cluster 365 | - show_advanced 366 | 367 | node_pool_shape: 368 | type: oci:core:instanceshape:name 369 | title: "Select a shape for the Worker Nodes instances" 370 | required: false 371 | dependsOn: 372 | compartmentId: compartment_ocid 373 | visible: 374 | and: 375 | - create_new_oke_cluster 376 | 377 | node_pool_node_shape_config_ocpus: 378 | type: integer 379 | minimum: 1 380 | maximum: 64 381 | title: "Number of OCPUs" 382 | visible: 383 | and: 384 | - and: 385 | - create_new_oke_cluster 386 | - or: 387 | - eq: 388 | - node_pool_shape 389 | - "VM.Standard.E3.Flex" 390 | - eq: 391 | - node_pool_shape 392 | - "VM.Standard.E4.Flex" 393 | - eq: 394 | - node_pool_shape 395 | - "VM.Standard.A1.Flex" 396 | 397 | node_pool_node_shape_config_memory_in_gbs: 398 | type: integer 399 | minimum: 1 400 | maximum: 1024 401 | title: "Amount of memory (GB)" 402 | visible: 403 | and: 404 | - and: 405 | - create_new_oke_cluster 406 | - or: 407 | - eq: 408 | - node_pool_shape 409 | - "VM.Standard.E3.Flex" 410 | - eq: 411 | - node_pool_shape 412 | - "VM.Standard.E4.Flex" 413 | - eq: 414 | - node_pool_shape 415 | - "VM.Standard.A1.Flex" 416 | 417 | image_operating_system: 418 | type: enum 419 | title: "Image OS" 420 | enum: 421 | - "Oracle Linux" 422 | required: false 423 | visible: 424 | and: 425 | - create_new_oke_cluster 426 | - show_advanced 427 | 428 | image_operating_system_version: 429 | type: string 430 | required: false 431 | title: "Image OS Version" 432 | visible: 433 | and: 434 | - create_new_oke_cluster 435 | - show_advanced 436 | 437 | create_dynamic_group_for_nodes_in_compartment: 438 | type: boolean 439 | title: "Create Dynamic Group for Worker Nodes in the Compartment" 440 | required: false 441 | visible: 442 | and: 443 | - show_advanced 444 | 445 | existent_dynamic_group_for_nodes_in_compartment: 446 | type: string 447 | required: false 448 | title: "Existent Dynamic Group" 449 | visible: 450 | and: 451 | - and: 452 | - show_advanced 453 | - or: 454 | - create_compartment_policies 455 | - create_tenancy_policies 456 | - not: 457 | - create_dynamic_group_for_nodes_in_compartment 458 | 459 | create_compartment_policies: 460 | type: boolean 461 | title: "Create Compartment Policies" 462 | required: false 463 | visible: 464 | and: 465 | - show_advanced 466 | 467 | create_tenancy_policies: 468 | type: boolean 469 | title: "Create Tenancy Policies" 470 | required: false 471 | visible: 472 | and: 473 | - show_advanced 474 | 475 | project_description: 476 | type: string 477 | title: "DevOps Project Description" 478 | description: "A short description for the DevOps project" 479 | default: "DevOps Project for OKE deployment" 480 | required: false 481 | visible: 482 | and: 483 | - show_advanced 484 | 485 | build_pipeline_stage_display_name: 486 | type: string 487 | title: "DevOps Build Pipeline Stage Name" 488 | description: "Name for the DevOps Build Pipeline Stage" 489 | required: false 490 | visible: true 491 | 492 | build_pipeline_display_name: 493 | type: string 494 | title: "DevOps Build Pipeline Display Name" 495 | description: "Name for the DevOps Build Pipeline Description" 496 | required: false 497 | visible: true 498 | 499 | build_pipeline_description: 500 | type: string 501 | title: "DevOps Build Pipeline Description" 502 | description: "A short description for the DevOps Build Pipeline Description" 503 | required: false 504 | visible: true 505 | 506 | repository_name: 507 | type: string 508 | title: "DevOps Repository Name" 509 | description: "Name for DevOps Repository" 510 | required: false 511 | visible: true 512 | 513 | repository_default_branch: 514 | type: string 515 | title: "DevOps Repository Default Branch" 516 | description: "Choose Defaulf Branch for DevOps Repository" 517 | required: false 518 | visible: true 519 | 520 | repository_description: 521 | type: string 522 | title: "DevOps Repository Description" 523 | description: "A short description for the DevOps Repository" 524 | required: false 525 | visible: true 526 | 527 | git_repo: 528 | type: string 529 | title: "GitHub.com Repository URL" 530 | description: "GitHub.com Repository URL for making git clone command" 531 | required: false 532 | visible: true 533 | 534 | git_repo_name: 535 | type: string 536 | title: "GitHub.com Repository Name" 537 | description: "GitHub.com Repository Name for making git clone command" 538 | required: false 539 | visible: true 540 | 541 | build_pipeline_stage_build_source_collection_items_name: 542 | type: string 543 | title: "Build Pipeline Build Stage Source Collection Items Name" 544 | description: "Build Pipeline Build Stage Source Collection Items Name" 545 | required: false 546 | visible: true 547 | 548 | build_pipeline_stage_stage_execution_timeout_in_seconds: 549 | required: false 550 | title: "DevOps Build Pipeline Stage execution timeout (in sec)" 551 | description: "DevOps Build Pipeline Stage execution timeout (in sec)" 552 | minimum: 36000 553 | maximum: 360000 554 | multipleOf: 1 555 | default: 36000 556 | 557 | container_repository_is_public: 558 | type: boolean 559 | title: "Is Container Repository public?" 560 | required: false 561 | visible: true 562 | 563 | registry_display_name: 564 | type: string 565 | title: "Registry Display Name" 566 | description: "Registry Display Name" 567 | required: false 568 | visible: true 569 | 570 | deliver_artifact_stage_display_name: 571 | type: string 572 | title: "Deliver Artifact Stage Display Name" 573 | description: "DevOps Build Pipeline Deliver Artifact Stage Display Name" 574 | required: false 575 | visible: true 576 | 577 | deploy_stage_display_name: 578 | type: string 579 | title: "Deploy Stage Display Name" 580 | description: "DevOps Build Pipeline Deploy Stage Display Name" 581 | required: false 582 | visible: true 583 | 584 | deploy_artifact_display_name: 585 | type: string 586 | title: "Deploy Artifact Display Name" 587 | description: "Deploy Artifact Display Name" 588 | required: false 589 | visible: true 590 | 591 | deploy_pipeline_description: 592 | type: string 593 | title: "DevOps Deploy Pipeline Description" 594 | description: "A short description for the DevOps Deploy Pipeline" 595 | required: false 596 | visible: true 597 | 598 | deploy_stage_description: 599 | type: string 600 | title: "DevOps Deploy Stage Pipeline Description" 601 | description: "A short description for the DevOps Deploy Pipeline" 602 | required: false 603 | visible: true 604 | 605 | execute_deployment: 606 | type: boolean 607 | title: "Execure deployment?" 608 | required: false 609 | visible: true 610 | 611 | build_pipeline_stage_is_pass_all_parameters_enabled: 612 | type: boolean 613 | title: "Build Pipeline Stage: is pass all parameters enabled?" 614 | description: "DevOps Build Pipeline Deploy Stage - enable passing all parameters." 615 | required: false 616 | visible: true 617 | 618 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=oracle-devrel_terraform-oci-arch-ci-cd-devops 2 | sonar.organization=oracle-devrel 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | #sonar.projectName=test 6 | #sonar.projectVersion=1.0 7 | 8 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 9 | #sonar.sources=. 10 | 11 | # Encoding of the source code. Default is default system encoding 12 | #sonar.sourceEncoding=UTF-8 -------------------------------------------------------------------------------- /tags.tf: -------------------------------------------------------------------------------- 1 | ## Copyright © 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | resource "random_id" "tag" { 5 | byte_length = 2 6 | } 7 | 8 | resource "oci_identity_tag_namespace" "ArchitectureCenterTagNamespace" { 9 | provider = oci.home_region 10 | compartment_id = var.compartment_ocid 11 | description = "ArchitectureCenterTagNamespace" 12 | name = "ArchitectureCenter\\ci-cd-pipe-oci-devops-${random_id.tag.hex}" 13 | 14 | provisioner "local-exec" { 15 | command = "sleep 10" 16 | } 17 | } 18 | 19 | resource "oci_identity_tag" "ArchitectureCenterTag" { 20 | provider = oci.home_region 21 | description = "ArchitectureCenterTag" 22 | name = "release" 23 | tag_namespace_id = oci_identity_tag_namespace.ArchitectureCenterTagNamespace.id 24 | 25 | validator { 26 | validator_type = "ENUM" 27 | values = ["release", "${var.release}"] 28 | } 29 | 30 | provisioner "local-exec" { 31 | command = "sleep 120" 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2022, Oracle and/or its affiliates. 2 | ## All rights reserved. The Universal Permissive License (UPL), Version 1.0 as shown at http://oss.oracle.com/licenses/upl 3 | 4 | variable "tenancy_ocid" {} 5 | variable "compartment_ocid" {} 6 | variable "user_ocid" {} 7 | variable "fingerprint" {} 8 | variable "private_key_path" {} 9 | variable "region" {} 10 | 11 | variable "app_name" { 12 | default = "DevOps" 13 | description = "Application name. Will be used as prefix to identify resources, such as OKE, VCN, DevOps, and others" 14 | } 15 | 16 | variable "oci_username" {} 17 | variable "oci_user_authtoken" {} 18 | 19 | variable "release" { 20 | description = "Reference Architecture Release (OCI Architecture Center)" 21 | default = "1.1.2" 22 | } 23 | 24 | variable "project_logging_config_retention_period_in_days" { 25 | default = 30 26 | } 27 | 28 | variable "project_description" { 29 | default = "DevOps CI/CD Sample Project" 30 | } 31 | 32 | 33 | variable "build_pipeline_description" { 34 | default = "build pipeline for Node.JS application" 35 | } 36 | 37 | variable "build_pipeline_display_name" { 38 | default = "NodeJS-build-pipeline" 39 | } 40 | 41 | variable "repository_name" { 42 | default = "nodejs" 43 | } 44 | 45 | variable "repository_default_branch" { 46 | default = "main" 47 | } 48 | 49 | variable "repository_description" { 50 | default = "nodejs sample application" 51 | } 52 | 53 | variable "git_repo" { 54 | default = "https://github.com/oracle-quickstart/oci-devops-node.git" 55 | } 56 | 57 | variable "git_repo_name" { 58 | default = "oci-devops-node" 59 | } 60 | 61 | variable "build_pipeline_stage_build_pipeline_stage_predecessor_collection_items_id" { 62 | default = "id" 63 | } 64 | 65 | variable "build_pipeline_stage_build_pipeline_stage_type" { 66 | default = "BUILD" 67 | } 68 | 69 | variable "build_pipeline_stage_deliver_artifact_stage_type" { 70 | default = "DELIVER_ARTIFACT" 71 | } 72 | 73 | variable "build_pipeline_stage_deploy_stage_type" { 74 | default = "TRIGGER_DEPLOYMENT_PIPELINE" 75 | } 76 | 77 | variable "build_pipeline_stage_build_source_collection_items_branch" { 78 | default = "main" 79 | } 80 | 81 | variable "build_pipeline_stage_build_source_collection_items_connection_type" { 82 | default = "DEVOPS_CODE_REPOSITORY" 83 | } 84 | 85 | variable "build_pipeline_stage_build_source_collection_items_name" { 86 | default = "node_express" 87 | } 88 | 89 | variable "build_pipeline_stage_build_spec_file" { 90 | default = "" 91 | } 92 | 93 | variable "build_pipeline_stage_deliver_artifact_collection_items_artifact_name" { 94 | default = "output01" 95 | } 96 | 97 | variable "build_pipeline_stage_display_name" { 98 | default = "nodejs-build-pipeline" 99 | } 100 | 101 | variable "build_pipeline_stage_description"{ 102 | default = "nodejs managed build stage" 103 | } 104 | 105 | variable "deliver_artifact_stage_display_name" { 106 | default = "deliver-artifact" 107 | } 108 | 109 | variable "deploy_stage_display_name" { 110 | default = "deploy-artifact" 111 | } 112 | 113 | variable "build_pipeline_stage_image" { 114 | default = "OL7_X86_64_STANDARD_10" 115 | } 116 | 117 | variable "build_pipeline_stage_wait_criteria_wait_duration" { 118 | default = "waitDuration" 119 | } 120 | 121 | variable "build_pipeline_stage_wait_criteria_wait_type" { 122 | default = "ABSOLUTE_WAIT" 123 | } 124 | 125 | variable "build_pipeline_stage_stage_execution_timeout_in_seconds" { 126 | default = 36000 127 | } 128 | 129 | /* 130 | variable "registry_display_name" { 131 | default = "node-express-getting-starter" 132 | } 133 | */ 134 | 135 | variable "container_repository_is_public" { 136 | default = true 137 | } 138 | 139 | variable "deploy_artifact_argument_substitution_mode" { 140 | default = "SUBSTITUTE_PLACEHOLDERS" 141 | } 142 | 143 | /* 144 | variable "deploy_artifact_display_name" { 145 | default = "node-express-getting-starter" 146 | } 147 | */ 148 | 149 | locals { 150 | ocir_docker_repository = join("", [lower(lookup(data.oci_identity_regions.current_region.regions[0], "key")), ".ocir.io"]) 151 | #ocir_docker_repository = join("", [lower(lookup(data.oci_identity_regions.home_region.regions[0], "key")), ".ocir.io"]) 152 | #ocir_namespace = lookup(data.oci_identity_tenancy.oci_tenancy, "name" ) 153 | ocir_namespace = lookup(data.oci_objectstorage_namespace.ns, "namespace") 154 | } 155 | 156 | #variable "ocir_region" { 157 | # default = "iad"} 158 | 159 | variable "deploy_artifact_deploy_artifact_source_deploy_artifact_source_type" { 160 | default = "OCIR" 161 | } 162 | 163 | variable "deploy_artifact_deploy_artifact_type" { 164 | default = "DOCKER_IMAGE" 165 | } 166 | 167 | variable "repository_repository_type" { 168 | default = "HOSTED" 169 | } 170 | 171 | variable "deploy_artifact_type" { 172 | default = "KUBERNETES_MANIFEST" 173 | } 174 | 175 | variable "deploy_pipeline_description" { 176 | default = "Devops CI/CD Pipeline demo for OKE" 177 | } 178 | 179 | variable "deploy_artifact_source_type" { 180 | default = "INLINE" 181 | } 182 | 183 | variable "deploy_pipeline_deploy_pipeline_parameters_items_default_value" { 184 | default = "example" 185 | } 186 | 187 | variable "deploy_pipeline_deploy_pipeline_parameters_items_description" { 188 | default = "exampleapp" 189 | } 190 | 191 | variable "deploy_pipeline_deploy_pipeline_parameters_items_name" { 192 | default = "namespace" 193 | } 194 | 195 | variable "deploy_stage_deploy_stage_type" { 196 | default = "OKE_DEPLOYMENT" 197 | } 198 | 199 | variable "deploy_stage_description" { 200 | default = "ci/cd deployment to OKE" 201 | } 202 | 203 | variable "execute_deployment" { 204 | default = true 205 | } 206 | 207 | variable "build_pipeline_stage_is_pass_all_parameters_enabled" { 208 | default = true 209 | } 210 | 211 | --------------------------------------------------------------------------------