├── .github └── workflows │ └── build-simple-orm.yml ├── .gitignore ├── LICENSE ├── README.md ├── devops_function ├── README.md ├── datasources.tf ├── devops-policies.tf ├── devops-variables.tf ├── devops.tf ├── functions-policies.tf ├── functions-setup.tf ├── functions.tf ├── functions │ ├── helloworldfn │ │ ├── func.py │ │ ├── func.yaml │ │ └── requirements.txt │ └── helloworldfn2 │ │ ├── func.py │ │ ├── func.yaml │ │ └── requirements.txt ├── images │ └── dev-ops-deployment-pipeline.png ├── locals.tf ├── manifest │ └── nginx.yaml ├── network.tf ├── providers.tf ├── schema.yaml ├── tags.tf ├── terraform.tfvars.example ├── tls.tf └── variables.tf ├── devops_instance_group ├── README.md ├── compute.tf ├── datasources.tf ├── devops.tf ├── file │ └── script.sh ├── images │ └── dev-ops-deployment-pipeline.png ├── manifest │ └── spec.yaml ├── network.tf ├── outputs.tf ├── policies.tf ├── providers.tf ├── schema.yaml ├── tags.tf ├── terraform.tfvars.example ├── tls.tf ├── userdata │ └── bootstrap └── variables.tf └── devops_oke ├── README.md ├── datasources.tf ├── devops-policies.tf ├── devops-variables.tf ├── devops.tf ├── images └── dev-ops-deployment-pipeline.png ├── manifest └── nginx.yaml ├── oke-network.tf ├── oke-outputs.tf ├── oke-security-lists.tf ├── oke-variables.tf ├── oke.tf ├── policies.tf ├── providers.tf ├── schema.yaml ├── tags.tf ├── terraform.tfvars.example ├── tls.tf └── variables.tf /.github/workflows/build-simple-orm.yml: -------------------------------------------------------------------------------- 1 | name: 'simple-orm-stack' 2 | 3 | on: [push, pull_request] 4 | env: 5 | PROJECT_WORKING_DIR: '/build-orm/' 6 | 7 | jobs: 8 | terraform_generate_orm_zip: 9 | name: 'Generate Stack Package' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v1 13 | - name: 'Terraform Init' 14 | uses: hashicorp/terraform-github-actions@master 15 | with: 16 | tf_actions_version: 0.12.17 17 | tf_actions_subcommand: 'init' 18 | tf_actions_working_dir: ${{ env.PROJECT_WORKING_DIR }} 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | - name: 'Terraform Validate' 22 | uses: hashicorp/terraform-github-actions@master 23 | with: 24 | tf_actions_version: 0.12.17 25 | tf_actions_subcommand: 'validate' 26 | tf_actions_working_dir: ${{ env.PROJECT_WORKING_DIR }} 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | - name: 'Terraform Apply' 30 | uses: hashicorp/terraform-github-actions@master 31 | with: 32 | tf_actions_version: 0.12.17 33 | tf_actions_subcommand: 'apply' 34 | tf_actions_working_dir: ${{ env.PROJECT_WORKING_DIR }} 35 | args: '-var="save_to"="export-dist"' 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | - name: Create Release 39 | id: create_release 40 | uses: actions/create-release@v1 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 43 | with: 44 | tag_name: ${{ github.ref }} 45 | release_name: Release ${{ github.ref }} 46 | body: | 47 | Changes in this Release 48 | - New ORM Stack template ${{ github.ref }} 49 | draft: true 50 | prerelease: true 51 | - name: Upload Release Asset 52 | id: upload-release-asset 53 | uses: actions/upload-release-asset@v1.0.1 54 | env: 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | with: 57 | upload_url: ${{ steps.create_release.outputs.upload_url }} 58 | asset_path: ${{ github.workspace }}${{ env.PROJECT_WORKING_DIR }}export-dist/orm.zip 59 | asset_name: orm-stack.zip 60 | asset_content_type: application/zip 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | *.zip* 8 | *.tfvars 9 | 10 | # Local .terraform lock files 11 | *.lock.* 12 | 13 | # General 14 | .DS_Store 15 | .AppleDouble 16 | .LSOverride 17 | 18 | # Icon must end with two \r 19 | Icon 20 | 21 | # Thumbnails 22 | ._* 23 | 24 | # Files that might appear in the root of a volume 25 | .DocumentRevisions-V100 26 | .fseventsd 27 | .Spotlight-V100 28 | .TemporaryItems 29 | .Trashes 30 | .VolumeIcon.icns 31 | .com.apple.timemachine.donotpresent 32 | 33 | # Directories potentially created on remote AFP share 34 | .AppleDB 35 | .AppleDesktop 36 | Network Trash Folder 37 | Temporary Items 38 | .apdisk 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2020 Oracle and/or its affiliates. All rights reserved. 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 person obtaining a copy of this 6 | software, associated documentation and/or data (collectively the "Software"), free of charge and under any and 7 | all copyright rights in the Software, and any and all patent rights owned or freely licensable by each licensor 8 | hereunder covering either (i) the unmodified Software as contributed to or provided by such licensor, or 9 | (ii) the Larger Works (as defined below), to deal in both 10 | 11 | (a) the Software, and 12 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if one is included with the Software 13 | (each a “Larger Work” to which the Software is contributed by such licensors), 14 | 15 | without restriction, including without limitation the rights to copy, create derivative works of, display, 16 | perform, and distribute the Software and make, use, sell, offer for sale, import, export, have made, and have 17 | sold the Software and the Larger Work(s), and to sublicense the foregoing rights on either these or other terms. 18 | 19 | This license is subject to the following condition: 20 | The above copyright notice and either this complete permission notice or at a minimum a reference to the UPL must 21 | be included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 24 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 26 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 | IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # oci-arch-devops 2 | 3 | These are Terraform code that deploy DevOps Services on [Oracle Cloud Infrastructure (OCI)](https://cloud.oracle.com/en_US/cloud-infrastructure). 4 | 5 | * [DevOps OKE](devops_oke) deploys DevOps Service with OCI Kubernetes Engine as target environment. 6 | * [DevOps Instance Group](devops_instance_group) deploys DevOps Service with Instance Group as target environment. 7 | * [DevOps Function](devops_function) deploys DevOps Service with OCI Function as target environment 8 | 9 | 10 | Please follow the instructions in [DevOps OKE](devops_oke) or [DevOps Instance Group](devops_instance_group) or [DevOps Function](devops_function) folders to deploy. 11 | -------------------------------------------------------------------------------- /devops_function/README.md: -------------------------------------------------------------------------------- 1 | # oci-arch-devops (devops_function) 2 | 3 | Rapid delivery of software is essential for efficiently running your applications in the cloud. Oracle DevOps service provides an end-to-end continuous deployment experience to developers. Oracle DevOps service includes deploying pipelines to automate your continuous software deployment process (CD) to Oracle Cloud Infrastructure (OCI) platforms: Container Engine for Kubernetes (OKE), Functions, and Compute instances. 4 | 5 | For details of the architecture, see [_Build a Continuous Deployment Pipeline using Oracle Cloud Infrastructure DevOps service_](https://docs.oracle.com/en/solutions/build-pipeline-using-devops/index.html) 6 | 7 | ## Prerequisites 8 | 9 | - Permission to `manage` the following types of resources in your Oracle Cloud Infrastructure tenancy: `vcns`, `internet-gateways`, `load-balancers`, `route-tables`, `security-lists`, `subnets`, and `instances`. 10 | 11 | - Quota to create the following resources: 1 VCN, 3 subnets, 1 Internet Gateway, 1 NAT Gateway, 2 route rules, ... 12 | 13 | If you don't have the required permissions and quota, contact your tenancy administrator. See [Policy Reference](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm), [Service Limits](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm), [Compartment Quotas](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcequotas.htm). 14 | 15 | ## Deploy Using Oracle Resource Manager 16 | 17 | 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-quickstart/oci-arch-devops/releases/latest/download/oci-arch-devops-function-stack-latest.zip) 18 | 19 | If you aren't already signed in, when prompted, enter the tenancy and user credentials. 20 | 21 | 2. Review and accept the terms and conditions. 22 | 23 | 3. Select the region where you want to deploy the stack. 24 | 25 | 4. Follow the on-screen prompts and instructions to create the stack. 26 | 27 | 5. After creating the stack, click **Terraform Actions**, and select **Plan**. 28 | 29 | 6. Wait for the job to be completed, and review the plan. 30 | 31 | To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. 32 | 33 | 7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. 34 | 35 | ## Deploy Using the Terraform CLI 36 | 37 | ### Clone of the repo 38 | Now, you'll want a local copy of this repo. You can make that with the commands: 39 | 40 | git clone https://github.com/oracle-quickstart/oci-arch-devops.git 41 | cd oci-arch-devops/devops_function 42 | ls 43 | 44 | ### Prerequisites 45 | First off, you'll need to do some pre-deploy setup. That's all detailed [here](https://github.com/cloud-partners/oci-prerequisites). 46 | 47 | Secondly, a sample `terraform.tfvars` file is provided in the repo. Please update the file with your tenancy details. 48 | 49 | Alternatively, you can create a `terraform.tfvars` file and populate with the following information as well as any additional information for your deployment: 50 | 51 | ``` 52 | # Authentication 53 | tenancy_ocid = "" 54 | user_ocid = "" 55 | fingerprint = "" 56 | private_key_path = "" 57 | 58 | # Region 59 | region = "" 60 | 61 | # Compartment 62 | compartment_ocid = "" 63 | 64 | # OCIR 65 | ocir_user_name = "" 66 | ocir_user_password = "" 67 | 68 | ```` 69 | 70 | ### Create the Resources 71 | Run the following commands: 72 | 73 | terraform init 74 | terraform plan 75 | terraform apply 76 | 77 | ### Destroy the Deployment 78 | When you no longer need the deployment, you can run this command to destroy the resources: 79 | 80 | terraform destroy 81 | 82 | ## Architecture Diagram 83 | 84 | ![](./images/dev-ops-deployment-pipeline.png) 85 | -------------------------------------------------------------------------------- /devops_function/datasources.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # Gets a list of Availability Domains 6 | data "oci_identity_availability_domains" "ADs" { 7 | compartment_id = var.tenancy_ocid 8 | } 9 | 10 | # Gets home and current regions 11 | data "oci_identity_tenancy" "tenant_details" { 12 | tenancy_id = var.tenancy_ocid 13 | 14 | provider = oci.current_region 15 | } 16 | 17 | data "oci_identity_regions" "home_region" { 18 | filter { 19 | name = "key" 20 | values = [data.oci_identity_tenancy.tenant_details.home_region_key] 21 | } 22 | 23 | provider = oci.current_region 24 | } 25 | 26 | 27 | data "oci_identity_tenancy" "oci_tenancy" { 28 | tenancy_id = var.tenancy_ocid 29 | } 30 | 31 | # OCI Services 32 | ## Available Services 33 | data "oci_core_services" "all_services" { 34 | filter { 35 | name = "name" 36 | values = ["All .* Services In Oracle Services Network"] 37 | regex = true 38 | } 39 | } 40 | 41 | data "oci_identity_regions" "oci_regions" { 42 | 43 | filter { 44 | name = "name" 45 | values = [var.region] 46 | } 47 | 48 | } 49 | 50 | data "oci_objectstorage_namespace" "os_namespace" { 51 | compartment_id = var.tenancy_ocid 52 | } 53 | 54 | 55 | # Randoms 56 | resource "random_string" "deploy_id" { 57 | length = 4 58 | special = false 59 | } 60 | 61 | -------------------------------------------------------------------------------- /devops_function/devops-policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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" "devops_pipln_dg" { 6 | count = var.create_dynamic_group_for_devops_pipln_in_compartment ? 1 : 0 7 | provider = oci.home_region 8 | compartment_id = var.tenancy_ocid 9 | name = "${var.app_name}-devops-pipln-dg-${random_string.deploy_id.result}" 10 | description = "${var.app_name} DevOps Pipeline Dynamic Group" 11 | matching_rule = "All {resource.type = 'devopsdeploypipeline', resource.compartment.id = '${var.compartment_ocid}'}" 12 | } 13 | 14 | resource "oci_identity_policy" "devops_compartment_policies" { 15 | count = var.create_compartment_policies ? 1 : 0 16 | depends_on = [oci_identity_dynamic_group.devops_pipln_dg] 17 | provider = oci.home_region 18 | name = "${var.app_name}-devops-compartment-policies-${random_string.deploy_id.result}" 19 | description = "${var.app_name} DevOps Compartment Policies" 20 | # compartment_id = var.compartment_ocid 21 | compartment_id = var.tenancy_ocid 22 | statements = local.devops_compartment_statements 23 | } 24 | 25 | locals { 26 | devops_pipln_dg = var.create_dynamic_group_for_devops_pipln_in_compartment ? oci_identity_dynamic_group.devops_pipln_dg.0.name : "void" 27 | allow_devops_manage_compartment_statements = [ 28 | # "Allow dynamic-group ${local.devops_pipln_dg} to manage all-resources in compartment id ${var.compartment_ocid}", 29 | "Allow dynamic-group ${local.devops_pipln_dg} to manage all-resources in tenancy", 30 | ] 31 | } 32 | 33 | -------------------------------------------------------------------------------- /devops_function/devops-variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 Dynamic Group and Policies 5 | variable "create_dynamic_group_for_nodes_in_compartment" { 6 | default = true 7 | } 8 | variable "existent_dynamic_group_for_nodes_in_compartment" { 9 | default = "" 10 | } 11 | variable "create_compartment_policies" { 12 | default = true 13 | } 14 | variable "create_tenancy_policies" { 15 | default = true 16 | } 17 | 18 | variable "deploy_pipeline_deploy_pipeline_parameters_items_default_value" { 19 | default = "defaultValue" 20 | } 21 | 22 | variable "deploy_pipeline_deploy_pipeline_parameters_items_description" { 23 | default = "description" 24 | } 25 | 26 | variable "deploy_pipeline_deploy_pipeline_parameters_items_name" { 27 | default = "name" 28 | } 29 | 30 | variable "project_description" { 31 | default = "DevOps Project for Function deployment" 32 | } 33 | variable "environment_type" { 34 | default = "FUNCTION" 35 | } 36 | 37 | variable "project_logging_config_display_name_prefix" { 38 | default = "fn-" 39 | } 40 | 41 | variable "project_logging_config_is_archiving_enabled" { 42 | default = false 43 | } 44 | 45 | variable "project_logging_config_retention_period_in_days" { 46 | default = 30 47 | } 48 | 49 | 50 | variable "deploy_artifact_source_type" { 51 | default = "OCIR" 52 | } 53 | 54 | variable "deploy_artifact_type" { 55 | default = "DOCKER_IMAGE" 56 | } 57 | 58 | variable "argument_substitution_mode" { 59 | default = "NONE" 60 | } 61 | 62 | variable "create_dynamic_group_for_devops_pipln_in_compartment" { 63 | default = true 64 | } 65 | 66 | variable "deploy_stage_deploy_stage_type" { 67 | default = "DEPLOY_FUNCTION" 68 | } 69 | 70 | variable "deploy_stage_namespace" { 71 | default = "default" 72 | } 73 | 74 | -------------------------------------------------------------------------------- /devops_function/devops.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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_logging_log_group" "test_log_group" { 5 | compartment_id = var.compartment_ocid 6 | display_name = "${var.app_name}_${random_string.deploy_id.result}_log_group" 7 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 8 | } 9 | 10 | resource "oci_logging_log" "test_log" { 11 | display_name = "${var.app_name}_${random_string.deploy_id.result}_log" 12 | log_group_id = oci_logging_log_group.test_log_group.id 13 | log_type = "SERVICE" 14 | 15 | configuration { 16 | source { 17 | category = "all" 18 | resource = oci_devops_project.test_project.id 19 | service = "devops" 20 | source_type = "OCISERVICE" 21 | } 22 | compartment_id = var.compartment_ocid 23 | } 24 | 25 | is_enabled = true 26 | retention_duration = var.project_logging_config_retention_period_in_days 27 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 28 | } 29 | 30 | resource "oci_ons_notification_topic" "test_notification_topic" { 31 | compartment_id = var.compartment_ocid 32 | name = "${var.app_name}_${random_string.deploy_id.result}_topic" 33 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 34 | } 35 | 36 | resource "oci_devops_project" "test_project" { 37 | compartment_id = var.compartment_ocid 38 | name = "${var.app_name}_${random_string.deploy_id.result}_devops_project" 39 | notification_config { 40 | topic_id = oci_ons_notification_topic.test_notification_topic.id 41 | } 42 | description = "${var.app_name}_${random_string.deploy_id.result}_devops_project" 43 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 44 | } 45 | 46 | resource "oci_devops_deploy_environment" "test_environment" { 47 | display_name = "${var.app_name}_${random_string.deploy_id.result}_devops_environment" 48 | description = "${var.app_name}_${random_string.deploy_id.result}_devops_environment" 49 | deploy_environment_type = "FUNCTION" 50 | project_id = oci_devops_project.test_project.id 51 | function_id = oci_functions_function.test_fn.id 52 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 53 | } 54 | 55 | resource "oci_devops_deploy_artifact" "test_deploy_ocir_artifact" { 56 | depends_on = [null_resource.FnPush2OCIR2] 57 | project_id = oci_devops_project.test_project.id 58 | deploy_artifact_type = var.deploy_artifact_type 59 | argument_substitution_mode = var.argument_substitution_mode 60 | deploy_artifact_source { 61 | deploy_artifact_source_type = var.deploy_artifact_source_type 62 | image_uri = "${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version2}" 63 | } 64 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 65 | } 66 | 67 | resource "oci_devops_deploy_pipeline" "test_deploy_pipeline" { 68 | project_id = oci_devops_project.test_project.id 69 | description = "${var.app_name}_${random_string.deploy_id.result}_devops_pipeline" 70 | display_name = "${var.app_name}_${random_string.deploy_id.result}_devops_pipeline" 71 | 72 | deploy_pipeline_parameters { 73 | items { 74 | name = var.deploy_pipeline_deploy_pipeline_parameters_items_name 75 | default_value = var.deploy_pipeline_deploy_pipeline_parameters_items_default_value 76 | description = var.deploy_pipeline_deploy_pipeline_parameters_items_description 77 | } 78 | } 79 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 80 | } 81 | 82 | resource "oci_devops_deploy_stage" "test_deploy_stage" { 83 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 84 | deploy_stage_predecessor_collection { 85 | items { 86 | id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 87 | } 88 | } 89 | deploy_stage_type = var.deploy_stage_deploy_stage_type 90 | 91 | 92 | description = "${var.app_name}_${random_string.deploy_id.result}_devops_deploy_stage" 93 | display_name = "${var.app_name}_${random_string.deploy_id.result}_devops_deploy_stage" 94 | 95 | namespace = var.deploy_stage_namespace 96 | function_deploy_environment_id = oci_devops_deploy_environment.test_environment.id 97 | docker_image_deploy_artifact_id = oci_devops_deploy_artifact.test_deploy_ocir_artifact.id 98 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 99 | } 100 | 101 | resource "oci_devops_deployment" "test_deployment" { 102 | count = var.execute_deployment ? 1 : 0 103 | depends_on = [null_resource.FnPush2OCIR2, oci_devops_deploy_stage.test_deploy_stage] 104 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 105 | deployment_type = "PIPELINE_DEPLOYMENT" 106 | display_name = "${var.app_name}_${random_string.deploy_id.result}_devops_deployment" 107 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 108 | } 109 | -------------------------------------------------------------------------------- /devops_function/functions-policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # Functions Policies 5 | 6 | resource "oci_identity_policy" "faas_read_repos_tenancy_policy" { 7 | provider = oci.home_region 8 | name = "${var.app_name}-faas-read-repos-tenancy-policy-${random_id.tag.hex}" 9 | description = "${var.app_name}-faas-read-repos-tenancy-policy-${random_id.tag.hex}" 10 | compartment_id = var.tenancy_ocid 11 | statements = ["Allow service FaaS to read repos in tenancy"] 12 | provisioner "local-exec" { 13 | command = "sleep 5" 14 | } 15 | } 16 | 17 | resource "oci_identity_policy" "admin_manage_function_family_policy" { 18 | provider = oci.home_region 19 | depends_on = [oci_identity_policy.faas_read_repos_tenancy_policy] 20 | name = "${var.app_name}-admin-manage-function-family-policy-${random_id.tag.hex}" 21 | description = "${var.app_name}-admin-manage-function-family-policy-${random_id.tag.hex}" 22 | compartment_id = var.compartment_ocid 23 | statements = ["Allow group Administrators to manage functions-family in compartment id ${var.compartment_ocid}", 24 | "Allow group Administrators to read metrics in compartment id ${var.compartment_ocid}"] 25 | provisioner "local-exec" { 26 | command = "sleep 5" 27 | } 28 | } 29 | 30 | resource "oci_identity_policy" "admin_use_vcn_family_policy" { 31 | provider = oci.home_region 32 | depends_on = [oci_identity_policy.admin_manage_function_family_policy] 33 | name = "${var.app_name}-admin-use-vcn-family-policy-${random_id.tag.hex}" 34 | description = "${var.app_name}-admin-use-vcn-family-policy-${random_id.tag.hex}" 35 | compartment_id = var.compartment_ocid 36 | statements = ["Allow group Administrators to use virtual-network-family in compartment id ${var.compartment_ocid}"] 37 | 38 | provisioner "local-exec" { 39 | command = "sleep 5" 40 | } 41 | } 42 | 43 | resource "oci_identity_policy" "faas_use_vcn_family_policy" { 44 | provider = oci.home_region 45 | depends_on = [oci_identity_policy.admin_use_vcn_family_policy] 46 | name = "${var.app_name}-faas-use-vcn-family-policy-${random_id.tag.hex}" 47 | description = "${var.app_name}-faas-use-vcn-family-policy-${random_id.tag.hex}" 48 | compartment_id = var.tenancy_ocid 49 | statements = ["Allow service FaaS to use virtual-network-family in compartment id ${var.compartment_ocid}"] 50 | 51 | provisioner "local-exec" { 52 | command = "sleep 5" 53 | } 54 | } 55 | 56 | resource "oci_identity_dynamic_group" "faas_dg" { 57 | provider = oci.home_region 58 | depends_on = [oci_identity_policy.faas_use_vcn_family_policy] 59 | name = "${var.app_name}-faas-dg-${random_id.tag.hex}" 60 | description = "${var.app_name}-faas-dg-${random_id.tag.hex}" 61 | compartment_id = var.tenancy_ocid 62 | matching_rule = "ALL {resource.type = 'fnfunc', resource.compartment.id = '${var.compartment_ocid}'}" 63 | 64 | provisioner "local-exec" { 65 | command = "sleep 5" 66 | } 67 | } 68 | 69 | resource "oci_identity_policy" "faas_dg_policy" { 70 | provider = oci.home_region 71 | depends_on = [oci_identity_dynamic_group.faas_dg] 72 | name = "${var.app_name}-faas-dg-policy-${random_id.tag.hex}" 73 | description = "${var.app_name}-faas-dg-policy-${random_id.tag.hex}" 74 | compartment_id = var.compartment_ocid 75 | statements = ["allow dynamic-group ${oci_identity_dynamic_group.faas_dg.name} to manage all-resources in compartment id ${var.compartment_ocid}"] 76 | 77 | provisioner "local-exec" { 78 | command = "sleep 5" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /devops_function/functions-setup.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "null_resource" "Login2OCIR" { 5 | depends_on = [oci_functions_application.test_fn_app, 6 | oci_identity_policy.faas_read_repos_tenancy_policy, 7 | oci_identity_policy.admin_manage_function_family_policy, 8 | oci_identity_dynamic_group.faas_dg, 9 | oci_identity_policy.faas_dg_policy] 10 | 11 | provisioner "local-exec" { 12 | command = "echo '${var.ocir_user_password}' | docker login ${local.ocir_docker_repository} --username ${local.ocir_namespace}/${var.ocir_user_name} --password-stdin" 13 | } 14 | } 15 | 16 | resource "null_resource" "FnPush2OCIR" { 17 | depends_on = [null_resource.Login2OCIR, oci_functions_application.test_fn_app] 18 | 19 | provisioner "local-exec" { 20 | command = "image=$(docker images | grep ${local.app_name_lower} | awk -F ' ' '{print $3}') ; docker rmi -f $image &> /dev/null ; echo $image" 21 | working_dir = "functions/${local.app_name_lower}" 22 | } 23 | 24 | provisioner "local-exec" { 25 | command = "fn build --verbose" 26 | working_dir = "functions/${local.app_name_lower}" 27 | } 28 | 29 | provisioner "local-exec" { 30 | command = "image=$(docker images | grep ${local.app_name_lower} | awk -F ' ' '{print $3}') ; docker tag $image ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version}" 31 | working_dir = "functions/${local.app_name_lower}" 32 | } 33 | 34 | provisioner "local-exec" { 35 | command = "docker push ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version}" 36 | working_dir = "functions/${local.app_name_lower}" 37 | } 38 | 39 | } 40 | 41 | resource "null_resource" "FnPush2OCIR2" { 42 | depends_on = [null_resource.Login2OCIR, null_resource.FnPush2OCIR, oci_functions_function.test_fn] 43 | 44 | provisioner "local-exec" { 45 | command = "image=$(docker images | grep ${local.app_name_lower} | awk -F ' ' '{print $3}') ; docker rmi -f $image &> /dev/null ; echo $image" 46 | working_dir = "functions/${local.app_name_lower}2" 47 | } 48 | 49 | provisioner "local-exec" { 50 | command = "fn build --verbose" 51 | working_dir = "functions/${local.app_name_lower}2" 52 | } 53 | 54 | provisioner "local-exec" { 55 | command = "image=$(docker images | grep ${local.app_name_lower} | awk -F ' ' '{print $3}') ; docker tag $image ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version2}" 56 | working_dir = "functions/${local.app_name_lower}2" 57 | } 58 | 59 | provisioner "local-exec" { 60 | command = "docker push ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version2}" 61 | working_dir = "functions/${local.app_name_lower}2" 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /devops_function/functions.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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_functions_application" "test_fn_app" { 5 | compartment_id = var.compartment_ocid 6 | display_name = "${var.app_name}App" 7 | subnet_ids = [oci_core_subnet.fnsubnet.id] 8 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 9 | } 10 | 11 | resource "oci_functions_function" "test_fn" { 12 | depends_on = [null_resource.FnPush2OCIR] 13 | application_id = oci_functions_application.test_fn_app.id 14 | display_name = var.app_name 15 | image = "${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/${local.app_name_lower}:${var.app_version}" 16 | memory_in_mbs = "256" 17 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn/func.py: -------------------------------------------------------------------------------- 1 | # 2 | # oci-load-file-into-adw-python version 1.0. 3 | # 4 | # Copyright (c) 2020 Oracle, Inc. 5 | # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | # 7 | 8 | import io 9 | import json 10 | import requests 11 | 12 | from fdk import response 13 | 14 | 15 | def handler(ctx, data: io.BytesIO=None): 16 | 17 | return response.Response( 18 | ctx, 19 | response_data=json.dumps({"status": "Hello World! Version 0.0.1"}), 20 | headers={"Content-Type": "application/json"} 21 | ) 22 | -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn/func.yaml: -------------------------------------------------------------------------------- 1 | schema_version: 20180708 2 | name: helloworldfn 3 | version: 0.0.1 4 | runtime: python 5 | entrypoint: /python/bin/fdk /function/func.py handler 6 | memory: 256 7 | -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn/requirements.txt: -------------------------------------------------------------------------------- 1 | fdk 2 | requests -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn2/func.py: -------------------------------------------------------------------------------- 1 | # 2 | # oci-load-file-into-adw-python version 1.0. 3 | # 4 | # Copyright (c) 2020 Oracle, Inc. 5 | # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | # 7 | 8 | import io 9 | import json 10 | import requests 11 | 12 | from fdk import response 13 | 14 | 15 | def handler(ctx, data: io.BytesIO=None): 16 | 17 | return response.Response( 18 | ctx, 19 | response_data=json.dumps({"status": "Hello World! Version 0.0.2"}), 20 | headers={"Content-Type": "application/json"} 21 | ) 22 | -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn2/func.yaml: -------------------------------------------------------------------------------- 1 | schema_version: 20180708 2 | name: helloworldfn 3 | version: 0.0.2 4 | runtime: python 5 | entrypoint: /python/bin/fdk /function/func.py handler 6 | memory: 256 7 | -------------------------------------------------------------------------------- /devops_function/functions/helloworldfn2/requirements.txt: -------------------------------------------------------------------------------- 1 | fdk 2 | requests -------------------------------------------------------------------------------- /devops_function/images/dev-ops-deployment-pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-arch-devops/b74c2b07feae7bf69c876834bb5903cf4d708210/devops_function/images/dev-ops-deployment-pipeline.png -------------------------------------------------------------------------------- /devops_function/locals.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | locals { 5 | devops_compartment_statements = concat( 6 | local.allow_devops_manage_compartment_statements, 7 | ) 8 | } 9 | 10 | locals { 11 | app_name_lower = lower(var.app_name) 12 | } 13 | -------------------------------------------------------------------------------- /devops_function/manifest/nginx.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: devops-nginx 7 | name: nginx-deployment 8 | spec: 9 | replicas: 5 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: devops-nginx 13 | template: 14 | metadata: 15 | labels: 16 | app.kubernetes.io/name: devops-nginx 17 | spec: 18 | containers: 19 | - name: nginx 20 | image: nginx:1.20.0 21 | ports: 22 | - containerPort: 80 23 | protocol: TCP 24 | name: http 25 | --- 26 | apiVersion: v1 27 | kind: Service 28 | metadata: 29 | labels: 30 | app.kubernetes.io/name: devops-nginx 31 | name: nginx-service 32 | annotations: 33 | service.beta.kubernetes.io/oci-load-balancer-shape: "flexible" 34 | service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: 10 35 | service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: 10 36 | spec: 37 | ports: 38 | - name: http 39 | port: 80 40 | protocol: TCP 41 | targetPort: 80 42 | selector: 43 | app.kubernetes.io/name: devops-nginx 44 | type: LoadBalancer -------------------------------------------------------------------------------- /devops_function/network.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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_core_virtual_network" "vcn" { 5 | cidr_block = var.VCN-CIDR 6 | dns_label = "vcn" 7 | compartment_id = var.compartment_ocid 8 | display_name = "vcn" 9 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 10 | } 11 | 12 | resource "oci_core_internet_gateway" "igw" { 13 | compartment_id = var.compartment_ocid 14 | display_name = "igw" 15 | vcn_id = oci_core_virtual_network.vcn.id 16 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 17 | } 18 | 19 | 20 | resource "oci_core_route_table" "rt_via_igw" { 21 | compartment_id = var.compartment_ocid 22 | vcn_id = oci_core_virtual_network.vcn.id 23 | display_name = "rt_via_igw" 24 | route_rules { 25 | destination = "0.0.0.0/0" 26 | destination_type = "CIDR_BLOCK" 27 | network_entity_id = oci_core_internet_gateway.igw.id 28 | } 29 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 30 | } 31 | 32 | resource "oci_core_dhcp_options" "dhcpoptions1" { 33 | compartment_id = var.compartment_ocid 34 | vcn_id = oci_core_virtual_network.vcn.id 35 | display_name = "dhcpoptions1" 36 | 37 | // required 38 | options { 39 | type = "DomainNameServer" 40 | server_type = "VcnLocalPlusInternet" 41 | } 42 | 43 | // optional 44 | options { 45 | type = "SearchDomain" 46 | search_domain_names = ["example.com"] 47 | } 48 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 49 | } 50 | 51 | resource "oci_core_subnet" "fnsubnet" { 52 | cidr_block = var.fnsubnet-CIDR 53 | display_name = "fnsubnet" 54 | dns_label = "fnsub" 55 | compartment_id = var.compartment_ocid 56 | vcn_id = oci_core_virtual_network.vcn.id 57 | route_table_id = oci_core_route_table.rt_via_igw.id 58 | dhcp_options_id = oci_core_dhcp_options.dhcpoptions1.id 59 | security_list_ids = [oci_core_virtual_network.vcn.default_security_list_id] 60 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /devops_function/providers.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | terraform { 6 | required_version = ">= 0.14" 7 | required_providers { 8 | oci = { 9 | source = "hashicorp/oci" 10 | version = "4.34.0" 11 | } 12 | tls = { 13 | source = "hashicorp/tls" 14 | version = "2.0.1" # Latest version as March 2021 = 3.1.0. Using 2.0.1 (April, 2020) for ORM compatibility 15 | } 16 | local = { 17 | source = "hashicorp/local" 18 | version = "1.4.0" # Latest version as March 2021 = 2.1.0. Using 1.4.0 (September, 2019) for ORM compatibility 19 | } 20 | random = { 21 | source = "hashicorp/random" 22 | version = "2.3.0" # Latest version as March 2021 = 3.1.0. Using 2.3.0 (July, 2020) for ORM compatibility 23 | } 24 | } 25 | } 26 | 27 | provider "oci" { 28 | tenancy_ocid = var.tenancy_ocid 29 | region = var.region 30 | 31 | user_ocid = var.user_ocid 32 | fingerprint = var.fingerprint 33 | private_key_path = var.private_key_path 34 | } 35 | 36 | provider "oci" { 37 | alias = "home_region" 38 | tenancy_ocid = var.tenancy_ocid 39 | region = lookup(data.oci_identity_regions.home_region.regions[0], "name") 40 | 41 | user_ocid = var.user_ocid 42 | fingerprint = var.fingerprint 43 | private_key_path = var.private_key_path 44 | } 45 | 46 | provider "oci" { 47 | alias = "current_region" 48 | tenancy_ocid = var.tenancy_ocid 49 | region = var.region 50 | 51 | user_ocid = var.user_ocid 52 | fingerprint = var.fingerprint 53 | private_key_path = var.private_key_path 54 | } 55 | -------------------------------------------------------------------------------- /devops_function/schema.yaml: -------------------------------------------------------------------------------- 1 | title: "Use OCI DevOps with Functions" 2 | description: "Create Function and DevOps Deploy service to manage your Functions deployments." 3 | schemaVersion: 1.1.0 4 | version: "20190304" 5 | locale: "en" 6 | 7 | ################# 8 | # Variable Groups 9 | ################# 10 | 11 | variableGroups: 12 | - title: General Configuration 13 | visible: false 14 | variables: 15 | - tenancy_ocid 16 | - region 17 | - user_ocid 18 | - fingerprint 19 | - private_key_path 20 | - network_cidrs 21 | - app_version 22 | - app_version2 23 | - deploy_pipeline_deploy_pipeline_parameters_items_default_value 24 | - deploy_pipeline_deploy_pipeline_parameters_items_description 25 | - deploy_pipeline_deploy_pipeline_parameters_items_name 26 | - compartment_ocid 27 | - release 28 | 29 | - title: Required Configuration 30 | visible: true 31 | variables: 32 | - app_name 33 | - ocir_user_name 34 | - ocir_user_password 35 | - execute_deployment 36 | - show_advanced 37 | 38 | - title: DevOps Project 39 | visible: true 40 | variables: 41 | - compartment_id 42 | - project_description 43 | - project_logging_config_is_archiving_enabled 44 | - project_logging_config_display_name_prefix 45 | - project_logging_config_retention_period_in_days 46 | 47 | - title: Function & Network Configuration 48 | visible: true 49 | variables: 50 | - VCN-CIDR 51 | - fnsubnet-CIDR 52 | - ocir_repo_name 53 | 54 | - title: DevOps Environments 55 | visible: 56 | and: 57 | - show_advanced 58 | variables: 59 | - environment_type 60 | 61 | - title: DevOps Artifacts 62 | visible: 63 | and: 64 | - show_advanced 65 | variables: 66 | - deploy_artifact_source_type 67 | - deploy_artifact_type 68 | - argument_substitution_mode 69 | 70 | - title: Pipelines & Stages 71 | visible: 72 | and: 73 | - show_advanced 74 | variables: 75 | - deploy_stage_deploy_stage_type 76 | - deploy_stage_namespace 77 | 78 | - title: Policy Settings 79 | description: Policy setting for the stack deployment 80 | visible: true 81 | variables: 82 | - create_dynamic_group_for_devops_pipln_in_compartment 83 | - create_dynamic_group_for_nodes_in_compartment 84 | - existent_dynamic_group_for_nodes_in_compartment 85 | - create_compartment_policies 86 | - create_tenancy_policies 87 | 88 | 89 | ###################### 90 | # Variable Definitions 91 | ###################### 92 | 93 | variables: 94 | 95 | compartment_id: 96 | type: oci:identity:compartment:id 97 | title: "Compartment" 98 | description: "The compartment in which to create resources" 99 | required: true 100 | 101 | app_name: 102 | type: string 103 | title: "HelloWorldFn" 104 | required: true 105 | 106 | show_advanced: 107 | type: boolean 108 | title: "Show advanced options?" 109 | description: "Shows advanced options, allowing enable customer-managed encryption keys, select your ssh key, select/unselect cluster utilities, do not create policies, and other advanced options" 110 | visible: true 111 | default: false 112 | 113 | execute_deployment: 114 | type: boolean 115 | title: "Execute deployment in DevOps Pipeline?" 116 | description: "Choose if you want to start deployment in DevOps Pipeline as a part of this Terraform automation." 117 | visible: true 118 | default: false 119 | 120 | ## Function 121 | 122 | VCN-CIDR: 123 | type: string 124 | required: false 125 | default: "10.0.0.0/16" 126 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 127 | description: "VCN CIDR block where you want to create the App/Function resources." 128 | 129 | fnsubnet-CIDR: 130 | type: string 131 | required: false 132 | default: "10.0.1.0/24" 133 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 134 | description: "Subnet CIDR block where you want to create the App/Function resources." 135 | 136 | ocir_repo_name: 137 | type: string 138 | required: true 139 | visibile: true 140 | title: "OCIR repository name" 141 | description: "Oracle Cloud Infrastructure Registry repository name (for example functions)" 142 | 143 | ocir_user_name: 144 | type: string 145 | required: true 146 | visibile: true 147 | title: "OCIR username" 148 | description: "Oracle Cloud Infrastructure Registry username (your OCI username)" 149 | 150 | ocir_user_password: 151 | type: password 152 | required: true 153 | visibile: true 154 | title: "OCIR user password" 155 | description: "Oracle Cloud Infrastructure Registry user password (your OCI user authtoken)" 156 | 157 | 158 | ## DevOps 159 | 160 | project_description: 161 | type: string 162 | title: "Project description" 163 | description: "Choose DevOps Project description" 164 | default: "DevOps Project for Function deployment" 165 | required: false 166 | 167 | project_logging_config_is_archiving_enabled: 168 | type: boolean 169 | title: "Archiving enabled for Project Logging" 170 | description: "Archiving enabled for Project Logging" 171 | default: false 172 | required: true 173 | visible: 174 | and: 175 | - show_advanced 176 | 177 | project_logging_config_display_name_prefix: 178 | type: string 179 | title: "Prefix for Logging Config" 180 | description: "Prefix for Logging Config" 181 | default: "fn-" 182 | required: true 183 | visible: 184 | and: 185 | - show_advanced 186 | 187 | project_logging_config_retention_period_in_days: 188 | type: number 189 | title: "Project Logs retention period" 190 | description: "Days to retain logs from the Project." 191 | minimum: 1 192 | maximum: 128 193 | multipleOf: 1 194 | default: 30 195 | required: true 196 | visible: 197 | and: 198 | - show_advanced 199 | 200 | ############# 201 | # Environment 202 | ############# 203 | 204 | environment_type: 205 | type: enum 206 | enum: 207 | - "FUNCTION" 208 | title: "Environment Type" 209 | description: "The type of environment to target. Stack currently supports only FUNCTION" 210 | default: "FUNCTION" 211 | visible: 212 | and: 213 | - show_advanced 214 | 215 | ############ 216 | # Artifacts 217 | ############ 218 | deploy_artifact_source_type: 219 | type: enum 220 | enum: 221 | - "OCIR" 222 | title: "Artifact Source Type" 223 | description: "The source type of artifact. Stack currently supports only OCIR" 224 | default: "OCIR" 225 | 226 | deploy_artifact_type: 227 | type: enum 228 | enum: 229 | - "DOCKER_IMAGE" 230 | title: "Artifact Type" 231 | description: "The type of Artifact. Stack currently supports only DOCKER_IMAGE" 232 | default: "DOCKER_IMAGE" 233 | 234 | argument_substitution_mode: 235 | type: enum 236 | enum: 237 | - "NONE" 238 | title: "Argument substitution for the Artifact" 239 | description: "Artifacts can have arguments that are substituted with values are runtime. Stack currently supports only NONE" 240 | default: "NONE" 241 | 242 | ########### 243 | # Pipeline 244 | ########### 245 | create_dynamic_group_for_devops_pipln_in_compartment: 246 | type: boolean 247 | title: "Create a Dynamic Group for DevOps Pipelines" 248 | description: "You need to be an administrator to do this. Alternatively you can have the administrator create Dynamic group for you." 249 | default: true 250 | 251 | deploy_stage_deploy_stage_type: 252 | type: enum 253 | enum: 254 | - "DEPLOY_FUNCTION" 255 | title: "Stage Type" 256 | description: "DevOps Stage Type" 257 | default: "DEPLOY_FUNCTION" 258 | 259 | deploy_stage_namespace: 260 | type: string 261 | title: "Namespace to use" 262 | description: "namespace to use for deployment." 263 | default: "default" 264 | 265 | create_dynamic_group_for_nodes_in_compartment: 266 | type: boolean 267 | title: "Create Dynamic Group for Worker Nodes in the Compartment" 268 | required: true 269 | visible: 270 | and: 271 | - show_advanced 272 | 273 | existent_dynamic_group_for_nodes_in_compartment: 274 | type: string 275 | required: true 276 | title: "Existent Dynamic Group" 277 | visible: 278 | and: 279 | - and: 280 | - show_advanced 281 | - or: 282 | - create_compartment_policies 283 | - create_tenancy_policies 284 | - not: 285 | - create_dynamic_group_for_nodes_in_compartment 286 | 287 | create_compartment_policies: 288 | type: boolean 289 | title: "Create Compartment Policies" 290 | required: true 291 | visible: 292 | and: 293 | - show_advanced 294 | 295 | create_tenancy_policies: 296 | type: boolean 297 | title: "Create Tenancy Policies" 298 | required: true 299 | visible: 300 | and: 301 | - show_advanced 302 | 303 | 304 | 305 | -------------------------------------------------------------------------------- /devops_function/tags.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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\\devops_function-${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", "1.11"] 28 | } 29 | 30 | provisioner "local-exec" { 31 | command = "sleep 120" 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /devops_function/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | # Authentication 2 | tenancy_ocid = "ocid1.tenancy.oc1.." 3 | user_ocid = "ocid1.user.oc1.." 4 | fingerprint = "1c.." 5 | private_key_path = "~/.oci/oci_api_key.pem" 6 | 7 | # Region 8 | region = "us-ashburn-1" 9 | 10 | # Compartment 11 | compartment_ocid = "ocid1.compartment.oc1." 12 | 13 | # OCI Registry 14 | ocir_user_name = "identitycloudservice/" 15 | ocir_user_password = "baVe(...)L#Z_." 16 | 17 | # Set to TRUE if you want to automatically start DevOps Pipeline Deployment. 18 | update_function_with_new_image = true 19 | -------------------------------------------------------------------------------- /devops_function/tls.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "tls_private_key" "public_private_key_pair" { 5 | algorithm = "RSA" 6 | } 7 | -------------------------------------------------------------------------------- /devops_function/variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "user_ocid" {} 6 | variable "fingerprint" {} 7 | variable "private_key_path" {} 8 | variable "compartment_ocid" {} 9 | variable "region" {} 10 | 11 | variable "app_name" { 12 | default = "HelloWorldFn" 13 | description = "Application name. Will be used as prefix to identify resources, such as Function, VCN, DevOps, and others" 14 | } 15 | 16 | variable "release" { 17 | description = "Reference Architecture Release (OCI Architecture Center)" 18 | default = "1.11" 19 | } 20 | 21 | variable "execute_deployment" { 22 | # default = false 23 | default = true 24 | } 25 | 26 | variable "app_version" { 27 | default = "0.0.1" 28 | } 29 | 30 | variable "app_version2" { 31 | default = "0.0.2" 32 | } 33 | 34 | # ORM Schema visual control variables 35 | variable "show_advanced" { 36 | default = false 37 | } 38 | 39 | 40 | variable "VCN-CIDR" { 41 | default = "10.0.0.0/16" 42 | } 43 | 44 | variable "fnsubnet-CIDR" { 45 | default = "10.0.1.0/24" 46 | } 47 | 48 | variable "ocir_repo_name" { 49 | default = "functions" 50 | } 51 | 52 | variable "ocir_user_name" { 53 | sensitive = true 54 | default = "" 55 | } 56 | 57 | variable "ocir_user_password" { 58 | sensitive = true 59 | default = "" 60 | } 61 | 62 | # OCIR repo name & namespace 63 | 64 | locals { 65 | ocir_docker_repository = join("", [lower(lookup(data.oci_identity_regions.oci_regions.regions[0], "key")), ".ocir.io"]) 66 | ocir_namespace = lookup(data.oci_objectstorage_namespace.os_namespace, "namespace") 67 | } 68 | -------------------------------------------------------------------------------- /devops_instance_group/README.md: -------------------------------------------------------------------------------- 1 | # oci-arch-devops (devops_instance_group) 2 | 3 | Rapid delivery of software is essential for efficiently running your applications in the cloud. Oracle DevOps service provides an end-to-end continuous deployment experience to developers. Oracle DevOps service includes deploying pipelines to automate your continuous software deployment process (CD) to Oracle Cloud Infrastructure (OCI) platforms: Container Engine for Kubernetes (OKE), Functions, and Compute instances. 4 | 5 | For details of the architecture, see [_Build a Continuous Deployment Pipeline using Oracle Cloud Infrastructure DevOps service_](https://docs.oracle.com/en/solutions/build-pipeline-using-devops/index.html) 6 | 7 | ## Prerequisites 8 | 9 | - Permission to `manage` the following types of resources in your Oracle Cloud Infrastructure tenancy: `vcns`, `internet-gateways`, `load-balancers`, `route-tables`, `security-lists`, `subnets`, and `instances`. 10 | 11 | - Quota to create the following resources: 1 VCN, 3 subnets, 1 Internet Gateway, 1 NAT Gateway, 2 route rules, ... 12 | 13 | If you don't have the required permissions and quota, contact your tenancy administrator. See [Policy Reference](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm), [Service Limits](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm), [Compartment Quotas](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcequotas.htm). 14 | 15 | ## Deploy Using Oracle Resource Manager 16 | 17 | 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-quickstart/oci-arch-devops/releases/latest/download/oci-arch-devops-instance-group-stack-latest.zip) 18 | 19 | If you aren't already signed in, when prompted, enter the tenancy and user credentials. 20 | 21 | 2. Review and accept the terms and conditions. 22 | 23 | 3. Select the region where you want to deploy the stack. 24 | 25 | 4. Follow the on-screen prompts and instructions to create the stack. 26 | 27 | 5. After creating the stack, click **Terraform Actions**, and select **Plan**. 28 | 29 | 6. Wait for the job to be completed, and review the plan. 30 | 31 | To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. 32 | 33 | 7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. 34 | 35 | ## Deploy Using the Terraform CLI 36 | 37 | ### Clone of the repo 38 | Now, you'll want a local copy of this repo. You can make that with the commands: 39 | 40 | git clone https://github.com/oracle-quickstart/oci-arch-devops.git 41 | cd oci-arch-devops/devops_instance_group 42 | ls 43 | 44 | ### Prerequisites 45 | First off, you'll need to do some pre-deploy setup. That's all detailed [here](https://github.com/cloud-partners/oci-prerequisites). 46 | 47 | Secondly, a sample `terraform.tfvars` file is provided in the repo. Please update the file with your tenancy details. 48 | 49 | Alternatively, you can create a `terraform.tfvars` file and populate with the following information as well as any additional information for your deployment: 50 | 51 | ``` 52 | # Authentication 53 | tenancy_ocid = "" 54 | user_ocid = "" 55 | fingerprint = "" 56 | private_key_path = "" 57 | 58 | # SSH Keys 59 | ssh_private_key = "" 60 | 61 | # Region 62 | region = "" 63 | 64 | # Compartment 65 | compartment_ocid = "" 66 | 67 | ```` 68 | 69 | ### Create the Resources 70 | Run the following commands: 71 | 72 | terraform init 73 | terraform plan 74 | terraform apply 75 | 76 | Note: 77 | In order to test the deployment, grab the public ip of the compute instance and paste it on the browser to see the application running. 78 | 79 | 80 | ### Destroy the Deployment 81 | When you no longer need the deployment, you can run this command to destroy the resources: 82 | 83 | terraform destroy 84 | 85 | ## Architecture Diagram 86 | 87 | ![](./images/dev-ops-deployment-pipeline.png) 88 | -------------------------------------------------------------------------------- /devops_instance_group/compute.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # This Terraform script provisions a compute instance required for OCI DevOps service 5 | 6 | 7 | resource "oci_core_instance" "compute_instance" { 8 | availability_domain = var.availablity_domain_name == "" ? data.oci_identity_availability_domains.ADs.availability_domains[0]["name"] : var.availablity_domain_name 9 | compartment_id = var.compartment_ocid 10 | display_name = "devops-instance" 11 | shape = var.instance_shape 12 | fault_domain = "FAULT-DOMAIN-1" 13 | 14 | shape_config { 15 | ocpus = var.instance_ocpus 16 | memory_in_gbs = var.instance_shape_config_memory_in_gbs 17 | } 18 | 19 | metadata = { 20 | ssh_authorized_keys = var.ssh_public_key == "" ? tls_private_key.public_private_key_pair.public_key_openssh : var.ssh_public_key 21 | user_data = base64encode(file("./userdata/bootstrap")) 22 | 23 | } 24 | 25 | create_vnic_details { 26 | subnet_id = oci_core_subnet.subnet.id 27 | display_name = "primaryvnic" 28 | assign_public_ip = true 29 | assign_private_dns_record = true 30 | } 31 | 32 | source_details { 33 | source_type = "image" 34 | source_id = lookup(data.oci_core_images.InstanceImageOCID.images[0], "id") 35 | boot_volume_size_in_gbs = "50" 36 | } 37 | 38 | timeouts { 39 | create = "60m" 40 | } 41 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 42 | } 43 | -------------------------------------------------------------------------------- /devops_instance_group/datasources.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # Get list of availability domains 5 | 6 | data "oci_identity_availability_domains" "ADs" { 7 | compartment_id = var.tenancy_ocid 8 | } 9 | 10 | data "oci_core_images" "InstanceImageOCID" { 11 | compartment_id = var.compartment_ocid 12 | operating_system = var.instance_os 13 | operating_system_version = var.linux_os_version 14 | 15 | shape = var.instance_shape 16 | sort_by = "TIMECREATED" 17 | sort_order = "DESC" 18 | } 19 | 20 | # Gets home and current regions 21 | 22 | data "oci_identity_tenancy" "tenant_details" { 23 | tenancy_id = var.tenancy_ocid 24 | provider = oci.current_region 25 | } 26 | 27 | data "oci_identity_regions" "home_region" { 28 | filter { 29 | name = "key" 30 | values = [data.oci_identity_tenancy.tenant_details.home_region_key] 31 | } 32 | 33 | provider = oci.current_region 34 | } 35 | 36 | # Randoms 37 | resource "random_string" "deploy_id" { 38 | length = 4 39 | special = false 40 | } 41 | -------------------------------------------------------------------------------- /devops_instance_group/devops.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 Artifact Repository 5 | 6 | resource "oci_artifacts_repository" "test_repository" { 7 | #Required 8 | compartment_id = var.compartment_ocid 9 | is_immutable = true 10 | repository_type = "GENERIC" 11 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 12 | } 13 | 14 | # Upload artifacts to repository 15 | 16 | resource "oci_generic_artifacts_content_artifact_by_path" "test_artifact" { 17 | #Required 18 | artifact_path = var.filename 19 | repository_id = oci_artifacts_repository.test_repository.id 20 | version = "1.0" 21 | content = file("${path.module}/file/${var.filename}") 22 | } 23 | 24 | resource "oci_artifacts_generic_artifact" "test_generic_artifact" { 25 | artifact_id = oci_generic_artifacts_content_artifact_by_path.test_artifact.id 26 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 27 | } 28 | 29 | # Create log and log group 30 | 31 | resource "oci_logging_log_group" "test_log_group" { 32 | compartment_id = var.compartment_ocid 33 | display_name = "devops_log_group_${random_string.deploy_id.result}" 34 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 35 | } 36 | 37 | resource "oci_logging_log" "test_log" { 38 | #Required 39 | display_name = "devops_log_group_log" 40 | log_group_id = oci_logging_log_group.test_log_group.id 41 | log_type = "SERVICE" 42 | 43 | #Optional 44 | configuration { 45 | #Required 46 | source { 47 | #Required 48 | category = "all" 49 | resource = oci_devops_project.test_project.id 50 | service = "devops" 51 | source_type = "OCISERVICE" 52 | } 53 | 54 | #Optional 55 | compartment_id = var.compartment_ocid 56 | } 57 | 58 | is_enabled = true 59 | retention_duration = var.project_logging_config_retention_period_in_days 60 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 61 | } 62 | 63 | # Create OCI Notification 64 | 65 | resource "oci_ons_notification_topic" "test_notification_topic" { 66 | compartment_id = var.compartment_ocid 67 | name = "${random_string.deploy_id.result}_devopstopic" 68 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 69 | } 70 | 71 | # Create devops project 72 | 73 | resource "oci_devops_project" "test_project" { 74 | compartment_id = var.compartment_ocid 75 | name = "devopsproject_${random_string.deploy_id.result}" 76 | 77 | notification_config { 78 | #Required 79 | topic_id = oci_ons_notification_topic.test_notification_topic.id 80 | } 81 | 82 | #Optional 83 | description = var.project_description 84 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 85 | } 86 | 87 | # Create environment for deployment - compute instance 88 | 89 | resource "oci_devops_deploy_environment" "test_deploy_instance_group_environment" { 90 | compute_instance_group_selectors { 91 | items { 92 | compute_instance_ids = [oci_core_instance.compute_instance.id] 93 | selector_type = "INSTANCE_IDS" 94 | } 95 | } 96 | deploy_environment_type = var.environment_type 97 | project_id = oci_devops_project.test_project.id 98 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 99 | } 100 | 101 | # Create artifact to use 102 | 103 | # Create deployment specification artifact to use 104 | 105 | resource "oci_devops_deploy_artifact" "test_deploy_artifact" { 106 | argument_substitution_mode = var.argument_substitution_mode 107 | deploy_artifact_type = "DEPLOYMENT_SPEC" 108 | project_id = oci_devops_project.test_project.id 109 | 110 | deploy_artifact_source { 111 | deploy_artifact_source_type = "INLINE" 112 | base64encoded_content = file("${path.module}/manifest/spec.yaml") 113 | } 114 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 115 | } 116 | 117 | # Create application artifact to use 118 | 119 | resource "oci_devops_deploy_artifact" "test_deploy_app_artifact" { 120 | argument_substitution_mode = var.argument_substitution_mode 121 | deploy_artifact_type = "GENERIC_FILE" 122 | project_id = oci_devops_project.test_project.id 123 | 124 | deploy_artifact_source { 125 | deploy_artifact_source_type = "GENERIC_ARTIFACT" 126 | repository_id = oci_artifacts_repository.test_repository.id 127 | deploy_artifact_version = "1.0" 128 | deploy_artifact_path = var.filename 129 | } 130 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 131 | } 132 | 133 | # Create deployment pipeline 134 | 135 | resource "oci_devops_deploy_pipeline" "test_deploy_pipeline" { 136 | #Required 137 | project_id = oci_devops_project.test_project.id 138 | description = "devops demo pipleline" 139 | display_name = "devopspipeline" 140 | 141 | deploy_pipeline_parameters { 142 | items { 143 | name = var.deploy_pipeline_deploy_pipeline_parameters_items_name 144 | default_value = var.deploy_pipeline_deploy_pipeline_parameters_items_default_value 145 | description = var.deploy_pipeline_deploy_pipeline_parameters_items_description 146 | } 147 | } 148 | 149 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 150 | } 151 | 152 | # Create deployment stages in the pipeline 153 | 154 | resource "oci_devops_deploy_stage" "test_deploy_stage" { 155 | #Required 156 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 157 | deploy_stage_predecessor_collection { 158 | #Required 159 | items { 160 | #Required - firt statge has the predecessor ID as pipeline ID 161 | id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 162 | } 163 | } 164 | deploy_stage_type = var.deploy_stage_deploy_stage_type 165 | 166 | 167 | description = "deploy pipeline stage" 168 | display_name = "deployinstance" 169 | 170 | deployment_spec_deploy_artifact_id = oci_devops_deploy_artifact.test_deploy_artifact.id 171 | deploy_artifact_ids = [oci_devops_deploy_artifact.test_deploy_app_artifact.id] 172 | namespace = var.deploy_stage_namespace 173 | compute_instance_group_deploy_environment_id = oci_devops_deploy_environment.test_deploy_instance_group_environment.id 174 | 175 | rollout_policy { 176 | batch_count = "5" 177 | batch_delay_in_seconds = "10" 178 | policy_type = "COMPUTE_INSTANCE_GROUP_LINEAR_ROLLOUT_POLICY_BY_COUNT" 179 | } 180 | 181 | rollback_policy { 182 | policy_type = "AUTOMATED_STAGE_ROLLBACK_POLICY" 183 | } 184 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 185 | } 186 | 187 | # Invoke the deployment 188 | 189 | resource "oci_devops_deployment" "test_deployment" { 190 | count = var.execute_deployment ? 1 : 0 191 | depends_on = [oci_devops_deploy_stage.test_deploy_stage] 192 | #Required 193 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 194 | deployment_type = "PIPELINE_DEPLOYMENT" 195 | 196 | #Optional 197 | display_name = "devopsdeployment" 198 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 199 | } 200 | 201 | -------------------------------------------------------------------------------- /devops_instance_group/file/script.sh: -------------------------------------------------------------------------------- 1 | sudo yum -y update; sudo yum -y install httpd; sudo firewall-cmd --permanent --add-port=80/tcp; sudo firewall-cmd --permanent --add-port=443/tcp; sudo firewall-cmd --reload; sudo systemctl start httpd; 2 | sudo echo ' Hello World Service

Hello. Is this the Deployment you are looking for?

New Deployment - '${version}'

' > /tmp/genericArtifactDemo/output; 3 | sudo touch /var/www/html/index.html; 4 | sudo cp /tmp/genericArtifactDemo/output /var/www/html/index.html; 5 | sudo systemctl stop httpd; 6 | sudo systemctl start httpd; 7 | 8 | -------------------------------------------------------------------------------- /devops_instance_group/images/dev-ops-deployment-pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-arch-devops/b74c2b07feae7bf69c876834bb5903cf4d708210/devops_instance_group/images/dev-ops-deployment-pipeline.png -------------------------------------------------------------------------------- /devops_instance_group/manifest/spec.yaml: -------------------------------------------------------------------------------- 1 | version: 1.0 2 | component: deployment 3 | runAs: root 4 | env: 5 | variables: 6 | version: "v1.0" 7 | files: 8 | # This section is to define how the files in the artifact shall 9 | # be put on the compute instance 10 | - source: / 11 | destination: /tmp/genericArtifactDemo 12 | steps: 13 | # This section is to define the scripts that each step shall run on the instance after file copy. 14 | - stepType: Command 15 | name: Install Apache Web Server 16 | command: ./script.sh 17 | runAs: root 18 | timeoutInSeconds: 800 19 | -------------------------------------------------------------------------------- /devops_instance_group/network.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 VCN 5 | 6 | resource "oci_core_virtual_network" "vcn" { 7 | cidr_block = var.VCN-CIDR 8 | compartment_id = var.compartment_ocid 9 | display_name = "devops-vcn" 10 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 11 | } 12 | 13 | # Create internet gateway to allow public internet traffic 14 | 15 | resource "oci_core_internet_gateway" "ig" { 16 | compartment_id = var.compartment_ocid 17 | display_name = "internet-gateway" 18 | vcn_id = oci_core_virtual_network.vcn.id 19 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 20 | } 21 | 22 | # Create route table to connect vcn to internet gateway 23 | 24 | resource "oci_core_route_table" "rt" { 25 | compartment_id = var.compartment_ocid 26 | vcn_id = oci_core_virtual_network.vcn.id 27 | display_name = "route-table" 28 | route_rules { 29 | destination = "0.0.0.0/0" 30 | network_entity_id = oci_core_internet_gateway.ig.id 31 | } 32 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 33 | } 34 | 35 | # Create security list to allow internet access from compute and ssh access 36 | 37 | resource "oci_core_security_list" "sl" { 38 | compartment_id = var.compartment_ocid 39 | display_name = "security-list" 40 | vcn_id = oci_core_virtual_network.vcn.id 41 | 42 | egress_security_rules { 43 | destination = "0.0.0.0/0" 44 | protocol = "6" 45 | } 46 | 47 | ingress_security_rules { 48 | 49 | protocol = "6" 50 | source = "0.0.0.0/0" 51 | 52 | tcp_options { 53 | max = 22 54 | min = 22 55 | } 56 | } 57 | 58 | ingress_security_rules { 59 | protocol = "6" 60 | source = "0.0.0.0/0" 61 | 62 | tcp_options { 63 | max = 80 64 | min = 80 65 | } 66 | } 67 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 68 | } 69 | 70 | # Create regional subnets in vcn 71 | 72 | resource "oci_core_subnet" "subnet" { 73 | cidr_block = var.Subnet-CIDR 74 | display_name = "devops-subnet" 75 | compartment_id = var.compartment_ocid 76 | vcn_id = oci_core_virtual_network.vcn.id 77 | dhcp_options_id = oci_core_virtual_network.vcn.default_dhcp_options_id 78 | route_table_id = oci_core_route_table.rt.id 79 | security_list_ids = [oci_core_security_list.sl.id] 80 | 81 | provisioner "local-exec" { 82 | command = "sleep 5" 83 | } 84 | 85 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 86 | } 87 | -------------------------------------------------------------------------------- /devops_instance_group/outputs.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | output "generated_ssh_private_key" { 5 | value = tls_private_key.public_private_key_pair.private_key_pem 6 | sensitive = true 7 | } 8 | -------------------------------------------------------------------------------- /devops_instance_group/policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 group, user and polcies for devops service 5 | 6 | resource "oci_identity_group" "devops" { 7 | provider = oci.home_region 8 | name = "devops-group-${random_id.tag.hex}" 9 | description = "group created for devops" 10 | compartment_id = var.tenancy_ocid 11 | } 12 | 13 | resource "oci_identity_user" "devopsuser" { 14 | #Required 15 | provider = oci.home_region 16 | compartment_id = var.tenancy_ocid 17 | description = "user for devops" 18 | name = "devops-user-${random_id.tag.hex}" 19 | } 20 | 21 | resource "oci_identity_user_group_membership" "usergroupmem1" { 22 | depends_on = [oci_identity_group.devops] 23 | provider = oci.home_region 24 | group_id = oci_identity_group.devops.id 25 | user_id = oci_identity_user.devopsuser.id 26 | } 27 | 28 | resource "oci_identity_dynamic_group" "devopsgroup" { 29 | provider = oci.home_region 30 | name = "devopsdyngroup-${random_id.tag.hex}" 31 | description = "DevOps Pipeline Dynamic Group" 32 | compartment_id = var.tenancy_ocid 33 | matching_rule = "ALL {resource.type = 'devopsdeploypipeline', resource.compartment.id = '${var.compartment_ocid}'}" 34 | } 35 | 36 | resource "oci_identity_dynamic_group" "runcmddynamicgroup" { 37 | provider = oci.home_region 38 | name = "run_cmd_dyn_group-${random_id.tag.hex}" 39 | description = "run_cmd Pipeline Dynamic Group" 40 | compartment_id = var.tenancy_ocid 41 | matching_rule = "ANY {instance.id = '${oci_core_instance.compute_instance.id}'}" 42 | } 43 | 44 | resource "oci_identity_policy" "devopspolicy" { 45 | provider = oci.home_region 46 | name = "devops-policies-${random_id.tag.hex}" 47 | description = "policy created for devops" 48 | compartment_id = var.compartment_ocid 49 | 50 | statements = [ 51 | "Allow group ${oci_identity_group.devops.name} to manage devops-family in compartment id ${var.compartment_ocid}", 52 | "Allow group ${oci_identity_group.devops.name} to manage all-artifacts in compartment id ${var.compartment_ocid}", 53 | "Allow group ${oci_identity_group.devops.name} to use instance-agent-command-execution-family in compartment id ${var.compartment_ocid} where request.instance.id=${oci_core_instance.compute_instance.id}", 54 | "Allow dynamic-group ${oci_identity_dynamic_group.devopsgroup.name} to manage all-resources in compartment id ${var.compartment_ocid}", 55 | "Allow dynamic-group ${oci_identity_dynamic_group.runcmddynamicgroup.name} to use instance-agent-command-execution-family in compartment id ${var.compartment_ocid}", 56 | "Allow dynamic-group ${oci_identity_dynamic_group.runcmddynamicgroup.name} to manage buckets in compartment id ${var.compartment_ocid}", 57 | "Allow dynamic-group ${oci_identity_dynamic_group.runcmddynamicgroup.name} to manage objects in compartment id ${var.compartment_ocid}", 58 | "Allow dynamic-group ${oci_identity_dynamic_group.runcmddynamicgroup.name} to manage generic-artifacts in compartment id ${var.compartment_ocid}", 59 | "Allow dynamic-group ${oci_identity_dynamic_group.runcmddynamicgroup.name} to read all-artifacts in compartment id ${var.compartment_ocid}" 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /devops_instance_group/providers.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 = ">= 0.14" 6 | required_providers { 7 | oci = { 8 | source = "hashicorp/oci" 9 | version = "4.34.0" 10 | } 11 | tls = { 12 | source = "hashicorp/tls" 13 | version = "2.0.1" # Latest version as March 2021 = 3.1.0. Using 2.0.1 (April, 2020) for ORM compatibility 14 | } 15 | local = { 16 | source = "hashicorp/local" 17 | version = "1.4.0" # Latest version as March 2021 = 2.1.0. Using 1.4.0 (September, 2019) for ORM compatibility 18 | } 19 | random = { 20 | source = "hashicorp/random" 21 | version = "2.3.0" # Latest version as March 2021 = 3.1.0. Using 2.3.0 (July, 2020) for ORM compatibility 22 | } 23 | } 24 | } 25 | 26 | provider "oci" { 27 | tenancy_ocid = var.tenancy_ocid 28 | region = var.region 29 | 30 | user_ocid = var.user_ocid 31 | fingerprint = var.fingerprint 32 | private_key_path = var.private_key_path 33 | } 34 | 35 | provider "oci" { 36 | alias = "home_region" 37 | tenancy_ocid = var.tenancy_ocid 38 | region = lookup(data.oci_identity_regions.home_region.regions[0], "name") 39 | 40 | user_ocid = var.user_ocid 41 | fingerprint = var.fingerprint 42 | private_key_path = var.private_key_path 43 | } 44 | 45 | provider "oci" { 46 | alias = "current_region" 47 | tenancy_ocid = var.tenancy_ocid 48 | region = var.region 49 | 50 | user_ocid = var.user_ocid 51 | fingerprint = var.fingerprint 52 | private_key_path = var.private_key_path 53 | } 54 | -------------------------------------------------------------------------------- /devops_instance_group/schema.yaml: -------------------------------------------------------------------------------- 1 | title: "Use OCI DevOps with Instance Group" 2 | description: "Create DevOps Deploy Service to manage your Instance Group deployments." 3 | schemaVersion: 1.1.0 4 | version: "20190304" 5 | locale: "en" 6 | 7 | ################# 8 | # Variable Groups 9 | ################# 10 | 11 | variableGroups: 12 | - title: General Configuration 13 | visible: false 14 | variables: 15 | - tenancy_ocid 16 | - region 17 | - user_ocid 18 | - fingerprint 19 | - private_key_path 20 | - network_cidrs 21 | - app_version 22 | - app_version2 23 | - deploy_pipeline_deploy_pipeline_parameters_items_default_value 24 | - deploy_pipeline_deploy_pipeline_parameters_items_description 25 | - deploy_pipeline_deploy_pipeline_parameters_items_name 26 | - create_dynamic_group_for_devops_pipln_in_compartment 27 | - compartment_ocid 28 | - release 29 | 30 | - title: Required Configuration 31 | visible: true 32 | variables: 33 | - compartment_ocid 34 | - availablity_domain_name 35 | - execute_deployment 36 | - show_advanced 37 | 38 | - title: DevOps Project 39 | visible: true 40 | variables: 41 | - project_description 42 | - project_logging_config_retention_period_in_days 43 | 44 | - title: Network Configuration 45 | visible: true 46 | variables: 47 | - VCN-CIDR 48 | - Subnet-CIDR 49 | 50 | - title: DevOps Environments 51 | visible: 52 | and: 53 | - show_advanced 54 | variables: 55 | - environment_type 56 | - ssh_public_key 57 | - instance_shape 58 | - instance_ocpus 59 | - instance_shape_config_memory_in_gbs 60 | - instance_os 61 | - linux_os_version 62 | 63 | - title: DevOps Artifacts 64 | visible: 65 | and: 66 | - show_advanced 67 | variables: 68 | - filename 69 | - argument_substitution_mode 70 | 71 | - title: Pipelines & Stages 72 | visible: 73 | and: 74 | - show_advanced 75 | variables: 76 | - deploy_stage_deploy_stage_type 77 | - deploy_stage_namespace 78 | 79 | 80 | ###################### 81 | # Variable Definitions 82 | ###################### 83 | 84 | variables: 85 | 86 | compartment_ocid: 87 | type: oci:identity:compartment:id 88 | title: "Compartment" 89 | description: "The compartment in which to create resources" 90 | required: true 91 | 92 | show_advanced: 93 | type: boolean 94 | title: "Show advanced options?" 95 | description: "Shows advanced options, allowing enable customer-managed encryption keys, select your ssh key, select/unselect cluster utilities, do not create policies, and other advanced options" 96 | visible: true 97 | default: false 98 | 99 | execute_deployment: 100 | type: boolean 101 | title: "Execute deployment in DevOps Pipeline?" 102 | description: "Choose if you want to start deployment in DevOps Pipeline as a part of this Terraform automation." 103 | visible: true 104 | default: false 105 | 106 | ## Function 107 | 108 | VCN-CIDR: 109 | type: string 110 | required: false 111 | default: "10.0.0.0/16" 112 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 113 | description: "VCN CIDR block where you want to create the App/Function resources." 114 | 115 | Subnet-CIDR: 116 | type: string 117 | required: false 118 | default: "10.0.1.0/24" 119 | pattern: "^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\/(3[0-2]|[1-2]?[0-9])$" 120 | description: "Subnet CIDR block where you want to create the App/Function resources." 121 | 122 | 123 | ## DevOps 124 | 125 | project_description: 126 | type: string 127 | title: "Project description" 128 | description: "Choose DevOps Project description" 129 | default: "DevOps Project for Instance Group deployment" 130 | required: false 131 | 132 | project_logging_config_retention_period_in_days: 133 | type: number 134 | title: "Project Logs retention period" 135 | description: "Days to retain logs from the Project." 136 | minimum: 1 137 | maximum: 128 138 | multipleOf: 1 139 | default: 30 140 | required: true 141 | visible: 142 | and: 143 | - show_advanced 144 | 145 | ############# 146 | # Environment 147 | ############# 148 | 149 | environment_type: 150 | type: enum 151 | enum: 152 | - "COMPUTE_INSTANCE_GROUP" 153 | title: "Environment Type" 154 | description: "The type of environment to target. Stack currently supports only COMPUTE_INSTANCE_GROUP" 155 | default: "COMPUTE_INSTANCE_GROUP" 156 | visible: 157 | and: 158 | - show_advanced 159 | 160 | availablity_domain_name: 161 | type: oci:identity:availabilitydomain:name 162 | required: true 163 | visibile: true 164 | title: "Availability Domain to be chosen" 165 | description: "Availability Domain to be chosen" 166 | dependsOn: 167 | compartmentId: ${compartment_ocid} 168 | 169 | ssh_public_key: 170 | type: oci:core:ssh:publickey 171 | title: "Public SSH Key" 172 | description: "Choose public SSH Key to be uploaded into compute instances." 173 | required: false 174 | 175 | instance_shape: 176 | type: oci:core:instanceshape:name 177 | required: false 178 | title: "Instance Shape" 179 | description: "A shape is a template that determines the number of CPUs, amount of memory, and other resources allocated to a newly created instance." 180 | default: "VM.Standard.E3.Flex" 181 | dependsOn: 182 | compartmentId: ${compartment_ocid} 183 | 184 | instance_ocpus: 185 | type: number 186 | required: false 187 | minimum: 1 188 | maximum: 128 189 | multipleOf: 1 190 | default: 1 191 | title: "Flex Shape OCPUs" 192 | description: "Choose number of OCPUs for Flex Shape." 193 | visible: 194 | and: 195 | - or: 196 | - eq: 197 | - instance_shape 198 | - "VM.Standard.E3.Flex" 199 | - eq: 200 | - instance_shape 201 | - "VM.Standard.E4.Flex" 202 | - eq: 203 | - instance_shape 204 | - "VM.Standard.A1.Flex" 205 | - eq: 206 | - instance_shape 207 | - "VM.Optimized3.Flex" 208 | 209 | instance_shape_config_memory_in_gbs: 210 | type: number 211 | required: false 212 | minimum: 1 213 | maximum: 128 214 | multipleOf: 1 215 | default: 10 216 | title: "Flex Shape Memory (GB)" 217 | description: "Choose number GB for Flex Shape Memory." 218 | visible: 219 | and: 220 | - or: 221 | - eq: 222 | - instance_shape 223 | - "VM.Standard.E3.Flex" 224 | - eq: 225 | - instance_shape 226 | - "VM.Standard.E4.Flex" 227 | - eq: 228 | - instance_shape 229 | - "VM.Standard.A1.Flex" 230 | - eq: 231 | - instance_shape 232 | - "VM.Optimized3.Flex" 233 | 234 | instance_os: 235 | type: enum 236 | required: false 237 | title: "Instance OS" 238 | description: "An Operating System that determines the operating system for the instance." 239 | default: "Oracle Linux" 240 | enum: 241 | - "Oracle Linux" 242 | 243 | linux_os_version: 244 | type: enum 245 | required: false 246 | title: "Instance OS version" 247 | description: "An Operating System version that determines the operating system version for the instance." 248 | default: "8" 249 | enum: 250 | - "8" 251 | - "7.9" 252 | 253 | ############ 254 | # Artifacts 255 | ############ 256 | argument_substitution_mode: 257 | type: enum 258 | enum: 259 | - "NONE" 260 | title: "Argument substitution for the Artifact" 261 | description: "Artifacts can have arguments that are substituted with values are runtime. Stack currently supports only NONE" 262 | default: "NONE" 263 | 264 | ########### 265 | # Pipeline 266 | ########### 267 | create_dynamic_group_for_devops_pipln_in_compartment: 268 | type: boolean 269 | title: "Create a Dynamic Group for DevOps Pipelines" 270 | description: "You need to be an administrator to do this. Alternatively you can have the administrator create Dynamic group for you." 271 | default: true 272 | 273 | deploy_stage_deploy_stage_type: 274 | type: enum 275 | enum: 276 | - "COMPUTE_INSTANCE_GROUP_ROLLING_DEPLOYMENT" 277 | title: "Stage Type" 278 | description: "DevOps Stage Type" 279 | default: "COMPUTE_INSTANCE_GROUP_ROLLING_DEPLOYMENT" 280 | 281 | deploy_stage_namespace: 282 | type: string 283 | title: "Namespace to use" 284 | description: "namespace to use for deployment." 285 | default: "default" 286 | 287 | -------------------------------------------------------------------------------- /devops_instance_group/tags.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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\\devops_instance-group-${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", "1.3"] 28 | } 29 | 30 | provisioner "local-exec" { 31 | command = "sleep 120" 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /devops_instance_group/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | # Authentication 2 | tenancy_ocid = "ocid1.tenancy.oc1.." 3 | user_ocid = "ocid1.user.oc1.." 4 | fingerprint = "1c.." 5 | private_key_path = "~/.oci/oci_api_key.pem" 6 | 7 | # Region 8 | region = "us-ashburn-1" 9 | 10 | # Compartment 11 | compartment_ocid = "ocid1.compartment.oc1." 12 | -------------------------------------------------------------------------------- /devops_instance_group/tls.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "tls_private_key" "public_private_key_pair" { 5 | algorithm = "RSA" 6 | } 7 | -------------------------------------------------------------------------------- /devops_instance_group/userdata/bootstrap: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | users: 3 | - default 4 | - name: ocarun 5 | sudo: ALL=(ALL) NOPASSWD:ALL -------------------------------------------------------------------------------- /devops_instance_group/variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | variable "ssh_public_key" { 11 | default = "" 12 | } 13 | 14 | variable "execute_deployment" { 15 | default = false 16 | } 17 | 18 | variable "release" { 19 | description = "Reference Architecture Release (OCI Architecture Center)" 20 | default = "1.3" 21 | } 22 | 23 | variable "availablity_domain_name" { 24 | default = "" 25 | } 26 | variable "VCN-CIDR" { 27 | default = "10.0.0.0/16" 28 | } 29 | 30 | variable "Subnet-CIDR" { 31 | default = "10.0.1.0/24" 32 | } 33 | 34 | variable "instance_shape" { 35 | description = "Instance Shape" 36 | default = "VM.Standard.E3.Flex" 37 | } 38 | 39 | variable "instance_ocpus" { 40 | default = 1 41 | } 42 | 43 | variable "instance_shape_config_memory_in_gbs" { 44 | default = 1 45 | } 46 | 47 | variable "instance_os" { 48 | description = "Operating system for compute instances" 49 | default = "Oracle Linux" 50 | } 51 | 52 | variable "linux_os_version" { 53 | description = "Operating system version for all Linux instances" 54 | default = "7.9" 55 | } 56 | 57 | variable "create_dynamic_group_for_devops_pipln_in_compartment" { 58 | default = true 59 | } 60 | 61 | variable "project_logging_config_retention_period_in_days" { 62 | default = 30 63 | } 64 | 65 | variable "project_description" { 66 | default = "DevOps Project for Instance Group deployment" 67 | } 68 | 69 | variable "argument_substitution_mode" { 70 | default = "NONE" 71 | } 72 | 73 | variable "environment_type" { 74 | default = "COMPUTE_INSTANCE_GROUP" 75 | } 76 | 77 | variable "deploy_stage_namespace" { 78 | default = "default" 79 | } 80 | 81 | variable "filename" { 82 | default = "script.sh" 83 | } 84 | 85 | variable "deploy_stage_deploy_stage_type" { 86 | default = "COMPUTE_INSTANCE_GROUP_ROLLING_DEPLOYMENT" 87 | } 88 | 89 | variable "deploy_pipeline_deploy_pipeline_parameters_items_default_value" { 90 | default = "defaultValue" 91 | } 92 | 93 | variable "deploy_pipeline_deploy_pipeline_parameters_items_description" { 94 | default = "description" 95 | } 96 | 97 | variable "deploy_pipeline_deploy_pipeline_parameters_items_name" { 98 | default = "name" 99 | } 100 | -------------------------------------------------------------------------------- /devops_oke/README.md: -------------------------------------------------------------------------------- 1 | # oci-arch-devops (devops_oke) 2 | 3 | Rapid delivery of software is essential for efficiently running your applications in the cloud. Oracle DevOps service provides an end-to-end continuous deployment experience to developers. Oracle DevOps service includes deploying pipelines to automate your continuous software deployment process (CD) to Oracle Cloud Infrastructure (OCI) platforms: Container Engine for Kubernetes (OKE), Functions, and Compute instances. 4 | 5 | For details of the architecture, see [_Build a Continuous Deployment Pipeline using Oracle Cloud Infrastructure DevOps service_](https://docs.oracle.com/en/solutions/build-pipeline-using-devops/index.html) 6 | 7 | ## Prerequisites 8 | 9 | - Permission to `manage` the following types of resources in your Oracle Cloud Infrastructure tenancy: `vcns`, `internet-gateways`, `load-balancers`, `route-tables`, `security-lists`, `subnets`, and `instances`. 10 | 11 | - Quota to create the following resources: 1 VCN, 3 subnets, 1 Internet Gateway, 1 NAT Gateway, 2 route rules, ... 12 | 13 | If you don't have the required permissions and quota, contact your tenancy administrator. See [Policy Reference](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm), [Service Limits](https://docs.cloud.oracle.com/en-us/iaas/Content/General/Concepts/servicelimits.htm), [Compartment Quotas](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/resourcequotas.htm). 14 | 15 | ## Deploy Using Oracle Resource Manager 16 | 17 | 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-quickstart/oci-arch-devops/releases/latest/download/oci-arch-devops-oke-stack-latest.zip) 18 | 19 | If you aren't already signed in, when prompted, enter the tenancy and user credentials. 20 | 21 | 2. Review and accept the terms and conditions. 22 | 23 | 3. Select the region where you want to deploy the stack. 24 | 25 | 4. Follow the on-screen prompts and instructions to create the stack. 26 | 27 | 5. After creating the stack, click **Terraform Actions**, and select **Plan**. 28 | 29 | 6. Wait for the job to be completed, and review the plan. 30 | 31 | To make any changes, return to the Stack Details page, click **Edit Stack**, and make the required changes. Then, run the **Plan** action again. 32 | 33 | 7. If no further changes are necessary, return to the Stack Details page, click **Terraform Actions**, and select **Apply**. 34 | 35 | ## Deploy Using the Terraform CLI 36 | 37 | ### Clone the Repo 38 | 39 | Now, you'll want a local copy of this repo. You can make that with the commands: 40 | 41 | ``` 42 | git clone https://github.com/oracle-quickstart/oci-arch-devops.git 43 | cd oci-arch-devops/devops_oke 44 | ls 45 | ``` 46 | 47 | ### Prerequisites 48 | First off, you'll need to do some pre-deploy setup. That's all detailed [here](https://github.com/cloud-partners/oci-prerequisites). 49 | 50 | Secondly, a sample `terraform.tfvars` file is provided in the repo. Please update the file with your tenancy details. 51 | 52 | Alternatively, you can create a `terraform.tfvars` file and populate with the following information as well as any additional information for your deployment: 53 | 54 | ``` 55 | # Authentication 56 | tenancy_ocid = "" 57 | user_ocid = "" 58 | fingerprint = "" 59 | private_key_path = "" 60 | 61 | # Region 62 | region = "" 63 | 64 | # Availablity Domain 65 | availablity_domain_name = "" 66 | 67 | ```` 68 | 69 | ### Create the Resources 70 | Run the following commands: 71 | 72 | terraform init 73 | terraform plan 74 | terraform apply 75 | 76 | 77 | ### Destroy the Deployment 78 | When you no longer need the deployment, you can run this command to destroy the resources: 79 | 80 | terraform destroy 81 | 82 | ## Architecture Diagram 83 | 84 | ![](./images/dev-ops-deployment-pipeline.png) 85 | 86 | 87 | -------------------------------------------------------------------------------- /devops_oke/datasources.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # Gets a list of supported images based on the shape, operating_system and operating_system_version provided 6 | data "oci_core_images" "node_pool_images" { 7 | compartment_id = local.oke_compartment_id 8 | operating_system = var.image_operating_system 9 | operating_system_version = var.image_operating_system_version 10 | shape = var.node_pool_shape 11 | sort_by = "TIMECREATED" 12 | sort_order = "DESC" 13 | } 14 | 15 | data "oci_containerengine_cluster_option" "oke" { 16 | cluster_option_id = "all" 17 | } 18 | data "oci_containerengine_node_pool_option" "oke" { 19 | node_pool_option_id = "all" 20 | } 21 | 22 | # Gets a list of Availability Domains 23 | data "oci_identity_availability_domains" "ADs" { 24 | compartment_id = var.tenancy_ocid 25 | } 26 | 27 | # Gets home and current regions 28 | data "oci_identity_tenancy" "tenant_details" { 29 | tenancy_id = var.tenancy_ocid 30 | 31 | provider = oci.current_region 32 | } 33 | 34 | data "oci_identity_regions" "home_region" { 35 | filter { 36 | name = "key" 37 | values = [data.oci_identity_tenancy.tenant_details.home_region_key] 38 | } 39 | 40 | provider = oci.current_region 41 | } 42 | 43 | # Gets kubeconfig 44 | data "oci_containerengine_cluster_kube_config" "oke_cluster_kube_config" { 45 | cluster_id = var.create_new_oke_cluster ? module.oci-oke[0].cluster.id : var.existent_oke_cluster_id 46 | } 47 | 48 | # OCI Services 49 | ## Available Services 50 | data "oci_core_services" "all_services" { 51 | filter { 52 | name = "name" 53 | values = ["All .* Services In Oracle Services Network"] 54 | regex = true 55 | } 56 | } 57 | 58 | ## Object Storage 59 | data "oci_objectstorage_namespace" "ns" { 60 | compartment_id = local.oke_compartment_id 61 | } 62 | 63 | # Randoms 64 | resource "random_string" "deploy_id" { 65 | length = 4 66 | special = false 67 | } 68 | 69 | -------------------------------------------------------------------------------- /devops_oke/devops-policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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" "devops_pipln_dg" { 6 | name = "${local.app_name_normalized}-devops-pipln-dg-${random_string.deploy_id.result}" 7 | description = "${var.app_name} DevOps Pipeline Dynamic Group" 8 | compartment_id = var.tenancy_ocid 9 | matching_rule = "All {resource.type = 'devopsdeploypipeline', resource.compartment.id = '${var.compartment_id}'}" 10 | 11 | provider = oci.home_region 12 | 13 | count = var.create_dynamic_group_for_devops_pipln_in_compartment ? 1 : 0 14 | } 15 | resource "oci_identity_policy" "devops_compartment_policies" { 16 | name = "${local.app_name_normalized}-devops-compartment-policies-${random_string.deploy_id.result}" 17 | description = "${var.app_name} DevOps Compartment Policies" 18 | compartment_id = var.compartment_id 19 | statements = local.devops_compartment_statements 20 | 21 | depends_on = [oci_identity_dynamic_group.devops_pipln_dg] 22 | 23 | provider = oci.home_region 24 | 25 | count = var.create_compartment_policies ? 1 : 0 26 | } 27 | 28 | locals { 29 | 30 | devops_compartment_statements = concat( 31 | local.allow_devops_manage_compartment_statements, 32 | ) 33 | 34 | } 35 | 36 | locals { 37 | devops_pipln_dg = var.create_dynamic_group_for_devops_pipln_in_compartment ? oci_identity_dynamic_group.devops_pipln_dg.0.name : "void" 38 | 39 | allow_devops_manage_compartment_statements = [ 40 | "Allow dynamic-group ${local.devops_pipln_dg} to manage all-resources in compartment id ${var.compartment_id}", 41 | ] 42 | 43 | } 44 | -------------------------------------------------------------------------------- /devops_oke/devops-variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "log_group_display_name" { 5 | default = "devops-logs" 6 | } 7 | 8 | variable "notification_topic_name" { 9 | default = "devops-topic" 10 | } 11 | 12 | variable "execute_deployment" { 13 | default = false 14 | } 15 | 16 | variable "project_description" { 17 | default = "DevOps Project for OKE deployment" 18 | } 19 | 20 | variable "environment_display_name" { 21 | default = "DevOps OKE Environment" 22 | } 23 | variable "environment_description" { 24 | default = "OKE environment that can be targeted by devops" 25 | } 26 | variable "environment_type" { 27 | default = "OKE_CLUSTER" 28 | } 29 | 30 | variable "project_logging_config_display_name_prefix" { 31 | default = "demo-" 32 | } 33 | 34 | variable "project_logging_config_is_archiving_enabled" { 35 | default = false 36 | } 37 | 38 | variable "project_logging_config_retention_period_in_days" { 39 | default = 30 40 | } 41 | 42 | 43 | variable "deploy_artifact_source_type" { 44 | default = "INLINE" 45 | } 46 | 47 | variable "deploy_artifact_type" { 48 | default = "KUBERNETES_MANIFEST" 49 | } 50 | 51 | variable "argument_substitution_mode" { 52 | default = "NONE" 53 | } 54 | 55 | variable "create_dynamic_group_for_devops_pipln_in_compartment" { 56 | default = true 57 | } 58 | 59 | variable "deploy_pipeline_display_name" { 60 | default = "devops-oke-pipeline" 61 | } 62 | 63 | variable "deploy_pipeline_description" { 64 | default = "Devops Pipleline demo for OKE" 65 | } 66 | 67 | variable "deploy_stage_deploy_stage_type" { 68 | default = "OKE_DEPLOYMENT" 69 | } 70 | 71 | variable "deploy_stage_namespace" { 72 | default = "default" 73 | } 74 | 75 | variable "deploy_stage_display_name" { 76 | default = "deploy_OKE" 77 | } 78 | 79 | variable "deploy_stage_description" { 80 | default = "test deployment to OKE" 81 | } 82 | 83 | variable "deploy_pipeline_deploy_pipeline_parameters_items_default_value" { 84 | default = "defaultValue" 85 | } 86 | 87 | variable "deploy_pipeline_deploy_pipeline_parameters_items_description" { 88 | default = "description" 89 | } 90 | 91 | variable "deploy_pipeline_deploy_pipeline_parameters_items_name" { 92 | default = "name" 93 | } 94 | -------------------------------------------------------------------------------- /devops_oke/devops.tf: -------------------------------------------------------------------------------- 1 | resource "oci_logging_log_group" "test_log_group" { 2 | compartment_id = var.compartment_id 3 | display_name = "${local.app_name_normalized}_${random_string.deploy_id.result}_log_group" 4 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 5 | } 6 | 7 | resource "oci_logging_log" "test_log" { 8 | #Required 9 | display_name = "${local.app_name_normalized}_${random_string.deploy_id.result}_log" 10 | log_group_id = oci_logging_log_group.test_log_group.id 11 | log_type = "SERVICE" 12 | 13 | #Optional 14 | configuration { 15 | #Required 16 | source { 17 | #Required 18 | category = "all" 19 | resource = oci_devops_project.test_project.id 20 | service = "devops" 21 | source_type = "OCISERVICE" 22 | } 23 | 24 | #Optional 25 | compartment_id = var.compartment_id 26 | } 27 | 28 | is_enabled = true 29 | retention_duration = var.project_logging_config_retention_period_in_days 30 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 31 | } 32 | 33 | resource "oci_ons_notification_topic" "test_notification_topic" { 34 | compartment_id = var.compartment_id 35 | name = "${local.app_name_normalized}_${random_string.deploy_id.result}_topic" 36 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 37 | } 38 | 39 | resource "oci_devops_project" "test_project" { 40 | compartment_id = var.compartment_id 41 | # logging_config { 42 | # log_group_id = oci_logging_log_group.test_log_group.id 43 | # retention_period_in_days = var.project_logging_config_retention_period_in_days 44 | # } 45 | 46 | name = "${local.app_name_normalized}_${random_string.deploy_id.result}" 47 | notification_config { 48 | #Required 49 | topic_id = oci_ons_notification_topic.test_notification_topic.id 50 | } 51 | # LOgging config missing- Add that 52 | 53 | #Optional 54 | description = var.project_description 55 | #freeform_tags = var.project_freeform_tags 56 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 57 | } 58 | 59 | resource "oci_devops_deploy_environment" "test_environment" { 60 | display_name = "test_oke_env" 61 | description = "test oke based enviroment" 62 | deploy_environment_type = "OKE_CLUSTER" 63 | project_id = oci_devops_project.test_project.id 64 | cluster_id = var.create_new_oke_cluster ? module.oci-oke[0].cluster.id : var.existent_oke_cluster_id 65 | # cluster_id = oci_containerengine_cluster.oke_cluster[0].id 66 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 67 | } 68 | 69 | # Add var to choose between an existing Articat and an inline one 70 | 71 | resource "oci_devops_deploy_artifact" "test_deploy_artifact" { 72 | argument_substitution_mode = var.argument_substitution_mode 73 | deploy_artifact_type = var.deploy_artifact_type 74 | project_id = oci_devops_project.test_project.id 75 | 76 | deploy_artifact_source { 77 | deploy_artifact_source_type = var.deploy_artifact_source_type #INLINE,GENERIC_ARTIFACT_OCIR 78 | base64encoded_content = file("${path.module}/manifest/nginx.yaml") 79 | } 80 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 81 | } 82 | 83 | resource "oci_devops_deploy_pipeline" "test_deploy_pipeline" { 84 | #Required 85 | project_id = oci_devops_project.test_project.id 86 | description = var.deploy_pipeline_description 87 | display_name = var.deploy_pipeline_display_name 88 | 89 | deploy_pipeline_parameters { 90 | items { 91 | name = var.deploy_pipeline_deploy_pipeline_parameters_items_name 92 | default_value = var.deploy_pipeline_deploy_pipeline_parameters_items_default_value 93 | description = var.deploy_pipeline_deploy_pipeline_parameters_items_description 94 | } 95 | } 96 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 97 | } 98 | 99 | resource "oci_devops_deploy_stage" "test_deploy_stage" { 100 | #Required 101 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 102 | deploy_stage_predecessor_collection { 103 | #Required 104 | items { 105 | #Required - firt statge has the predecessor ID as pipeline ID 106 | id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 107 | } 108 | } 109 | deploy_stage_type = var.deploy_stage_deploy_stage_type 110 | 111 | 112 | description = var.deploy_stage_description 113 | display_name = var.deploy_stage_display_name 114 | 115 | kubernetes_manifest_deploy_artifact_ids = [oci_devops_deploy_artifact.test_deploy_artifact.id] 116 | namespace = var.deploy_stage_namespace 117 | oke_cluster_deploy_environment_id = oci_devops_deploy_environment.test_environment.id 118 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 119 | } 120 | 121 | # Invoke the deployment 122 | 123 | resource "oci_devops_deployment" "test_deployment" { 124 | count = var.execute_deployment ? 1 : 0 125 | depends_on = [oci_devops_deploy_stage.test_deploy_stage] 126 | #Required 127 | deploy_pipeline_id = oci_devops_deploy_pipeline.test_deploy_pipeline.id 128 | deployment_type = "PIPELINE_DEPLOYMENT" 129 | 130 | #Optional 131 | display_name = "devopsdeployment" 132 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 133 | } 134 | -------------------------------------------------------------------------------- /devops_oke/images/dev-ops-deployment-pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-quickstart/oci-arch-devops/b74c2b07feae7bf69c876834bb5903cf4d708210/devops_oke/images/dev-ops-deployment-pipeline.png -------------------------------------------------------------------------------- /devops_oke/manifest/nginx.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: devops-nginx 7 | name: nginx-deployment 8 | spec: 9 | replicas: 5 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: devops-nginx 13 | template: 14 | metadata: 15 | labels: 16 | app.kubernetes.io/name: devops-nginx 17 | spec: 18 | containers: 19 | - name: nginx 20 | image: nginx:1.20.0 21 | ports: 22 | - containerPort: 80 23 | protocol: TCP 24 | name: http 25 | --- 26 | apiVersion: v1 27 | kind: Service 28 | metadata: 29 | labels: 30 | app.kubernetes.io/name: devops-nginx 31 | name: nginx-service 32 | annotations: 33 | service.beta.kubernetes.io/oci-load-balancer-shape: "flexible" 34 | service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: 10 35 | service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: 10 36 | spec: 37 | ports: 38 | - name: http 39 | port: 80 40 | protocol: TCP 41 | targetPort: 80 42 | selector: 43 | app.kubernetes.io/name: devops-nginx 44 | type: LoadBalancer -------------------------------------------------------------------------------- /devops_oke/oke-network.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 ${var.app_name} VCN - ${random_string.deploy_id.result}" 9 | dns_label = "oke${random_string.deploy_id.result}" 10 | 11 | count = var.create_new_oke_cluster ? 1 : 0 12 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 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-${local.app_name_normalized}-${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 | 26 | count = var.create_new_oke_cluster ? 1 : 0 27 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 28 | } 29 | resource "oci_core_subnet" "oke_nodes_subnet" { 30 | cidr_block = lookup(var.network_cidrs, "SUBNET-REGIONAL-CIDR") 31 | compartment_id = local.oke_compartment_id 32 | display_name = "oke-nodes-subnet-${local.app_name_normalized}-${random_string.deploy_id.result}" 33 | dns_label = "okenodesn${random_string.deploy_id.result}" 34 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 35 | prohibit_public_ip_on_vnic = (var.cluster_workers_visibility == "Private") ? true : false 36 | 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 37 | dhcp_options_id = oci_core_virtual_network.oke_vcn[0].default_dhcp_options_id 38 | security_list_ids = [oci_core_security_list.oke_nodes_security_list[0].id] 39 | 40 | count = var.create_new_oke_cluster ? 1 : 0 41 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 42 | } 43 | 44 | resource "oci_core_subnet" "oke_lb_subnet" { 45 | cidr_block = lookup(var.network_cidrs, "LB-SUBNET-REGIONAL-CIDR") 46 | compartment_id = local.oke_compartment_id 47 | display_name = "oke-lb-subnet-${local.app_name_normalized}-${random_string.deploy_id.result}" 48 | dns_label = "okelbsn${random_string.deploy_id.result}" 49 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 50 | prohibit_public_ip_on_vnic = false 51 | route_table_id = oci_core_route_table.oke_public_route_table[0].id 52 | dhcp_options_id = oci_core_virtual_network.oke_vcn[0].default_dhcp_options_id 53 | security_list_ids = [oci_core_security_list.oke_lb_security_list[0].id] 54 | 55 | count = var.create_new_oke_cluster ? 1 : 0 56 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 57 | } 58 | 59 | resource "oci_core_route_table" "oke_private_route_table" { 60 | compartment_id = local.oke_compartment_id 61 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 62 | display_name = "oke-private-route-table-${local.app_name_normalized}-${random_string.deploy_id.result}" 63 | 64 | route_rules { 65 | description = "Traffic to the internet" 66 | destination = lookup(var.network_cidrs, "ALL-CIDR") 67 | destination_type = "CIDR_BLOCK" 68 | network_entity_id = oci_core_nat_gateway.oke_nat_gateway[0].id 69 | } 70 | route_rules { 71 | description = "Traffic to OCI services" 72 | destination = lookup(data.oci_core_services.all_services.services[0], "cidr_block") 73 | destination_type = "SERVICE_CIDR_BLOCK" 74 | network_entity_id = oci_core_service_gateway.oke_service_gateway[0].id 75 | } 76 | 77 | count = var.create_new_oke_cluster ? 1 : 0 78 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 79 | } 80 | resource "oci_core_route_table" "oke_public_route_table" { 81 | compartment_id = local.oke_compartment_id 82 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 83 | display_name = "oke-public-route-table-${local.app_name_normalized}-${random_string.deploy_id.result}" 84 | 85 | route_rules { 86 | description = "Traffic to/from internet" 87 | destination = lookup(var.network_cidrs, "ALL-CIDR") 88 | destination_type = "CIDR_BLOCK" 89 | network_entity_id = oci_core_internet_gateway.oke_internet_gateway[0].id 90 | } 91 | 92 | count = var.create_new_oke_cluster ? 1 : 0 93 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 94 | } 95 | 96 | resource "oci_core_nat_gateway" "oke_nat_gateway" { 97 | block_traffic = "false" 98 | compartment_id = local.oke_compartment_id 99 | display_name = "oke-nat-gateway-${local.app_name_normalized}-${random_string.deploy_id.result}" 100 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 101 | 102 | count = var.create_new_oke_cluster ? 1 : 0 103 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 104 | } 105 | 106 | resource "oci_core_internet_gateway" "oke_internet_gateway" { 107 | compartment_id = local.oke_compartment_id 108 | display_name = "oke-internet-gateway-${local.app_name_normalized}-${random_string.deploy_id.result}" 109 | enabled = true 110 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 111 | 112 | count = var.create_new_oke_cluster ? 1 : 0 113 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 114 | } 115 | 116 | resource "oci_core_service_gateway" "oke_service_gateway" { 117 | compartment_id = local.oke_compartment_id 118 | display_name = "oke-service-gateway-${local.app_name_normalized}-${random_string.deploy_id.result}" 119 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 120 | services { 121 | service_id = lookup(data.oci_core_services.all_services.services[0], "id") 122 | } 123 | 124 | count = var.create_new_oke_cluster ? 1 : 0 125 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 126 | } 127 | -------------------------------------------------------------------------------- /devops_oke/oke-outputs.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | value = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.private_key_pem : "No Keys Auto Generated" 11 | sensitive = true 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 | -------------------------------------------------------------------------------- /devops_oke/oke-security-lists.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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-${local.app_name_normalized}-${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 | 126 | count = var.create_new_oke_cluster ? 1 : 0 127 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 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-${local.app_name_normalized}-${random_string.deploy_id.result}" 133 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 134 | 135 | count = var.create_new_oke_cluster ? 1 : 0 136 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 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-${local.app_name_normalized}-${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 | 229 | count = var.create_new_oke_cluster ? 1 : 0 230 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 231 | } 232 | 233 | locals { 234 | http_port_number = "80" 235 | https_port_number = "443" 236 | k8s_api_endpoint_port_number = "6443" 237 | k8s_worker_to_control_plane_port_number = "12250" 238 | ssh_port_number = "22" 239 | tcp_protocol_number = "6" 240 | icmp_protocol_number = "1" 241 | all_protocols = "all" 242 | } 243 | -------------------------------------------------------------------------------- /devops_oke/oke-variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | # App Name Locals 179 | locals { 180 | app_name_normalized = substr(replace(lower(var.app_name), " ", "-"), 0, 6) 181 | app_name_for_db = regex("[[:alnum:]]{1,10}", var.app_name) 182 | } 183 | 184 | # Dictionary Locals 185 | locals { 186 | compute_flexible_shapes = [ 187 | "VM.Standard.E3.Flex", 188 | "VM.Standard.E4.Flex", 189 | "VM.Standard.A1.Flex" 190 | ] 191 | } 192 | -------------------------------------------------------------------------------- /devops_oke/oke.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | module "oci-oke" { 5 | count = var.create_new_oke_cluster ? 1 : 0 6 | source = "github.com/oracle-quickstart/oci-oke" 7 | tenancy_ocid = var.tenancy_ocid 8 | compartment_ocid = local.oke_compartment_id 9 | oke_cluster_name = "${var.app_name} (${random_string.deploy_id.result})" 10 | services_cidr = lookup(var.network_cidrs, "KUBERNETES-SERVICE-CIDR") 11 | pods_cidr = lookup(var.network_cidrs, "PODS-CIDR") 12 | cluster_options_add_ons_is_kubernetes_dashboard_enabled = var.cluster_options_add_ons_is_kubernetes_dashboard_enabled 13 | cluster_options_add_ons_is_tiller_enabled = false 14 | cluster_options_admission_controller_options_is_pod_security_policy_enabled = var.cluster_options_admission_controller_options_is_pod_security_policy_enabled 15 | pool_name = var.node_pool_name 16 | node_shape = var.node_pool_shape 17 | node_ocpus = var.node_pool_node_shape_config_ocpus 18 | node_memory = var.node_pool_node_shape_config_memory_in_gbs 19 | node_count = var.num_pool_workers 20 | node_pool_boot_volume_size_in_gbs = var.node_pool_boot_volume_size_in_gbs 21 | k8s_version = (var.k8s_version == "Latest") ? local.cluster_k8s_latest_version : var.k8s_version 22 | use_existing_vcn = true 23 | vcn_id = oci_core_virtual_network.oke_vcn[0].id 24 | is_api_endpoint_subnet_public = (var.cluster_endpoint_visibility == "Private") ? false : true 25 | api_endpoint_subnet_id = oci_core_subnet.oke_k8s_endpoint_subnet[0].id 26 | is_lb_subnet_public = true 27 | lb_subnet_id = oci_core_subnet.oke_lb_subnet[0].id 28 | is_nodepool_subnet_public = false 29 | nodepool_subnet_id = oci_core_subnet.oke_nodes_subnet[0].id 30 | ssh_public_key = var.generate_public_ssh_key ? tls_private_key.oke_worker_node_ssh_key.public_key_openssh : var.public_ssh_key 31 | availability_domain = data.oci_identity_availability_domains.ADs.availability_domains[0]["name"] 32 | defined_tags = { "${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}" = var.release } 33 | } 34 | 35 | resource "oci_identity_compartment" "oke_compartment" { 36 | compartment_id = var.compartment_id 37 | name = "${local.app_name_normalized}-${random_string.deploy_id.result}" 38 | description = "${var.app_name} ${var.oke_compartment_description} (Deployment ${random_string.deploy_id.result})" 39 | enable_delete = true 40 | 41 | count = var.create_new_compartment_for_oke ? 1 : 0 42 | } 43 | locals { 44 | oke_compartment_id = var.compartment_id 45 | } 46 | 47 | # Local kubeconfig for when using Terraform locally. Not used by Oracle Resource Manager 48 | resource "local_file" "kubeconfig" { 49 | content = data.oci_containerengine_cluster_kube_config.oke_cluster_kube_config.content 50 | filename = "generated/kubeconfig" 51 | } 52 | 53 | # Generate ssh keys to access Worker Nodes, if generate_public_ssh_key=true, applies to the pool 54 | resource "tls_private_key" "oke_worker_node_ssh_key" { 55 | algorithm = "RSA" 56 | rsa_bits = 2048 57 | } 58 | 59 | # Get OKE options 60 | locals { 61 | cluster_k8s_latest_version = reverse(sort(data.oci_containerengine_cluster_option.oke.kubernetes_versions))[0] 62 | node_pool_k8s_latest_version = reverse(sort(data.oci_containerengine_node_pool_option.oke.kubernetes_versions))[0] 63 | } 64 | 65 | # Checks if is using Flexible Compute Shapes 66 | locals { 67 | is_flexible_node_shape = contains(local.compute_flexible_shapes, var.node_pool_shape) 68 | } 69 | -------------------------------------------------------------------------------- /devops_oke/policies.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 = "${local.app_name_normalized}-oke-cluster-dg-${random_string.deploy_id.result}" 7 | description = "${var.app_name} 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 = "${local.app_name_normalized}-oke-cluster-compartment-policies-${random_string.deploy_id.result}" 17 | description = "${var.app_name} 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 = "${local.app_name_normalized}-kms-compartment-policies-${random_string.deploy_id.result}" 29 | description = "${var.app_name} 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 = "${local.app_name_normalized}-oke-cluster-tenancy-policies-${random_string.deploy_id.result}" 42 | description = "${var.app_name} 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 | } 98 | -------------------------------------------------------------------------------- /devops_oke/providers.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 | provider "oci" { 5 | tenancy_ocid = var.tenancy_ocid 6 | region = var.region 7 | 8 | user_ocid = var.user_ocid 9 | fingerprint = var.fingerprint 10 | private_key_path = var.private_key_path 11 | } 12 | 13 | provider "oci" { 14 | alias = "home_region" 15 | tenancy_ocid = var.tenancy_ocid 16 | region = lookup(data.oci_identity_regions.home_region.regions[0], "name") 17 | 18 | user_ocid = var.user_ocid 19 | fingerprint = var.fingerprint 20 | private_key_path = var.private_key_path 21 | } 22 | 23 | provider "oci" { 24 | alias = "current_region" 25 | tenancy_ocid = var.tenancy_ocid 26 | region = var.region 27 | 28 | user_ocid = var.user_ocid 29 | fingerprint = var.fingerprint 30 | private_key_path = var.private_key_path 31 | } 32 | -------------------------------------------------------------------------------- /devops_oke/schema.yaml: -------------------------------------------------------------------------------- 1 | title: "Use OCI DevOps with OKE" 2 | description: "Create and connect an OKE cluster and DevOps Deploy service to manage your Kubernetes deployments." 3 | schemaVersion: 1.1.0 4 | version: "20190304" 5 | locale: "en" 6 | 7 | 8 | ################# 9 | # Variable Groups 10 | ################# 11 | variableGroups: 12 | - title: General Configuration 13 | visible: false 14 | variables: 15 | - tenancy_ocid 16 | - region 17 | - node_pool_boot_volume_size_in_gbs 18 | - oke_compartment_description 19 | - user_ocid 20 | - fingerprint 21 | - private_key_path 22 | - network_cidrs 23 | - cluster_options_admission_controller_options_is_pod_security_policy_enabled 24 | - deploy_pipeline_deploy_pipeline_parameters_items_default_value 25 | - deploy_pipeline_deploy_pipeline_parameters_items_description 26 | - deploy_pipeline_deploy_pipeline_parameters_items_name 27 | - release 28 | 29 | - title: DevOps Project 30 | visible: true 31 | variables: 32 | - compartment_id 33 | - app_name 34 | - execute_deployment 35 | - show_advanced 36 | - log_group_display_name 37 | - notification_topic_name 38 | - project_description 39 | - project_logging_config_display_name_prefix 40 | - project_logging_config_is_archiving_enabled 41 | - project_logging_config_retention_period_in_days 42 | 43 | - title: DevOps Environments 44 | visible: 45 | and: 46 | - show_advanced 47 | variables: 48 | - environment_type 49 | - environment_description 50 | - environment_display_name 51 | 52 | - title: DevOps Artifacts 53 | visible: 54 | and: 55 | - show_advanced 56 | variables: 57 | - deploy_artifact_source_type 58 | - deploy_artifact_type 59 | - argument_substitution_mode 60 | 61 | 62 | - title: Pipelines & Stages 63 | visible: 64 | and: 65 | - show_advanced 66 | variables: 67 | - deploy_pipeline_display_name 68 | - deploy_pipeline_description 69 | - deploy_stage_deploy_stage_type 70 | - deploy_stage_namespace 71 | - deploy_stage_display_name 72 | - deploy_stage_description 73 | 74 | - title: Policy Settings 75 | description: Policy setting for the stack deployment 76 | visible: true 77 | variables: 78 | - create_dynamic_group_for_devops_pipln_in_compartment 79 | - create_dynamic_group_for_nodes_in_compartment 80 | - existent_dynamic_group_for_nodes_in_compartment 81 | - create_compartment_policies 82 | - create_tenancy_policies 83 | 84 | - title: Encryption Settings 85 | description: Policy setting for the stack deployment 86 | visible: true 87 | variables: 88 | - use_encryption_from_oci_vault 89 | - create_new_encryption_key 90 | - existent_encryption_key_id 91 | - create_vault_policies_for_group 92 | - user_admin_group_for_vault_policy 93 | 94 | 95 | 96 | - title: "OKE Cluster Configuration" 97 | variables: 98 | - create_new_oke_cluster 99 | - existent_oke_cluster_compartment_ocid 100 | - existent_oke_cluster_id 101 | - k8s_version 102 | - cluster_workers_visibility 103 | - cluster_endpoint_visibility 104 | - create_new_compartment_for_oke 105 | - cluster_options_add_ons_is_kubernetes_dashboard_enabled 106 | 107 | - title: "OKE Worker Nodes" 108 | variables: 109 | - cluster_autoscaler_enabled 110 | - num_pool_workers 111 | - cluster_autoscaler_min_nodes 112 | - cluster_autoscaler_max_nodes 113 | - existent_oke_nodepool_id_for_autoscaler 114 | - node_pool_shape 115 | - node_pool_node_shape_config_ocpus 116 | - node_pool_node_shape_config_memory_in_gbs 117 | - generate_public_ssh_key 118 | - public_ssh_key 119 | - image_operating_system 120 | - image_operating_system_version 121 | - node_pool_name 122 | 123 | 124 | ################# 125 | # Output Groups 126 | ################# 127 | outputGroups: 128 | - title: Service Endpoints 129 | outputs: 130 | - theia_public_ip 131 | - title: Generated Passwords 132 | outputs: 133 | - generated_ssh_private_key 134 | 135 | outputs: 136 | theia_public_ip: 137 | type: link 138 | title: Your Theia website 139 | description: Open Theia website 140 | generated_ssh_private_key: 141 | title: "Generated SSH Private Key" 142 | description: "Generated SSH Private Key" 143 | type: copyableString 144 | visible: true 145 | 146 | primaryOutputButton: theia_public_ip 147 | 148 | 149 | ###################### 150 | # Variable Definitions 151 | ###################### 152 | 153 | variables: 154 | 155 | compartment_id: 156 | type: oci:identity:compartment:id 157 | title: "Compartment" 158 | description: "The compartment in which to create resources" 159 | required: true 160 | 161 | app_name: 162 | type: string 163 | title: "Project Name" 164 | required: true 165 | 166 | execute_deployment: 167 | type: boolean 168 | title: "Execute deployment in DevOps Pipeline?" 169 | description: "Choose if you want to start deployment in DevOps Pipeline as a part of this Terraform automation." 170 | visible: true 171 | default: false 172 | 173 | show_advanced: 174 | type: boolean 175 | title: "Show advanced options?" 176 | description: "Shows advanced options, allowing enable customer-managed encryption keys, select your ssh key, select/unselect cluster utilities, do not create policies, and other advanced options" 177 | visible: true 178 | default: false 179 | 180 | ## DevOps 181 | 182 | log_group_display_name: 183 | type: string 184 | title: "Log Group Name" 185 | description: "Display name for the Log Group" 186 | default: "devops-logs" 187 | required: true 188 | visible: 189 | and: 190 | - show_advanced 191 | 192 | notification_topic_name: 193 | type: string 194 | title: "Notification Topic Name" 195 | description: "Name of the notification topic used for messages about the project" 196 | default: "devops-topic" 197 | required: true 198 | visible: 199 | and: 200 | - show_advanced 201 | 202 | 203 | project_description: 204 | type: string 205 | title: "DevOps Project Description" 206 | description: "A short description for the DevOps project" 207 | default: "DevOps Project for OKE deployment" 208 | required: true 209 | visible: 210 | and: 211 | - show_advanced 212 | 213 | 214 | project_logging_config_display_name_prefix: 215 | type: string 216 | title: "Prefix for Logging Config" 217 | description: "Display name for the Log Group" 218 | default: "demo-" 219 | required: true 220 | visible: 221 | and: 222 | - show_advanced 223 | 224 | project_logging_config_is_archiving_enabled: 225 | type: boolean 226 | title: "Archiving enabled for Project Logging " 227 | description: "Display name for the Log Group" 228 | default: false 229 | required: true 230 | visible: 231 | and: 232 | - show_advanced 233 | 234 | project_logging_config_retention_period_in_days: 235 | type: string 236 | title: "Project Logs retention period" 237 | description: "Days to retain logs from the Project." 238 | default: 30 239 | required: true 240 | visible: 241 | and: 242 | - show_advanced 243 | 244 | ############# 245 | # Environment 246 | ############# 247 | 248 | environment_type: 249 | type: enum 250 | enum: 251 | - "OKE_CLUSTER" 252 | title: "Environment Type" 253 | description: "The type of environment to target. Stack currently supports only OKE_CLUSTER" 254 | default: "OKE_CLUSTER" 255 | visible: 256 | and: 257 | - show_advanced 258 | environment_description: 259 | type: string 260 | title: "Environment Description" 261 | description: "Describe the DevOps Environment" 262 | default: "OKE environment that can be targeted by devops" 263 | visible: 264 | and: 265 | - show_advanced 266 | environment_display_name: 267 | type: string 268 | title: "Environment Name" 269 | description: "Name for the DevOps Environment" 270 | default: "DevOps OKE Environment" 271 | 272 | ############ 273 | # Artifacts 274 | ############ 275 | deploy_artifact_source_type: 276 | type: enum 277 | enum: 278 | - "INLINE" 279 | title: "Artifact Source Type" 280 | description: "The source type of artifact. Stack currently supports only INLINE" 281 | default: "INLINE" 282 | 283 | deploy_artifact_type: 284 | type: enum 285 | enum: 286 | - "KUBERNETES_MANIFEST" 287 | title: "Artifact Type" 288 | description: "The type of Artifact. Stack currently supports only KUBERNETES_MANIFEST" 289 | default: "KUBERNETES_MANIFEST" 290 | 291 | argument_substitution_mode: 292 | type: enum 293 | enum: 294 | - "NONE" 295 | title: "Argument substitution for the Artifact" 296 | description: "Artifacts can have arguments that are substituted with values are runtime. Stack currently supports only NONE" 297 | default: "NONE" 298 | 299 | ########### 300 | # Pipeline 301 | ########### 302 | create_dynamic_group_for_devops_pipln_in_compartment: 303 | type: boolean 304 | title: "Create a Dynamic Group for DevOps Pipelines" 305 | description: | 306 | You need to be an administrator to do this. 307 | 308 | Alternatively you can have the administrator create Dynamic group for you. 309 | default: true 310 | 311 | deploy_pipeline_display_name: 312 | type: string 313 | title: "Pipleline Name" 314 | description: "Display name for the Pipleline" 315 | default: "devops-oke-pipeline" 316 | 317 | deploy_pipeline_description: 318 | type: string 319 | title: "Pipeline Description" 320 | description: "Description for the Pipeline" 321 | default: "Devops Pipleline demo for OKE" 322 | 323 | deploy_stage_deploy_stage_type: 324 | type: enum 325 | enum: 326 | - "OKE_DEPLOYMENT" 327 | title: "Stage type" 328 | description: "Display name for the Log Group" 329 | default: "OKE_DEPLOYMENT" 330 | 331 | deploy_stage_namespace: 332 | type: string 333 | title: "Kubernetes Namespace to use" 334 | description: "Kubernetes namespace to use for deployment." 335 | default: "default" 336 | 337 | deploy_stage_display_name: 338 | type: string 339 | title: "Stage Name" 340 | description: "Name for the deployment stage." 341 | default: "deploy_OKE" 342 | 343 | deploy_stage_description: 344 | type: string 345 | title: "Stage Description" 346 | description: "Description for the deployment stage" 347 | default: "test deployment to OKE" 348 | 349 | #################### 350 | ## OKE 351 | #################### 352 | 353 | create_new_oke_cluster: 354 | type: boolean 355 | title: "Create new OKE Cluster" 356 | 357 | existent_oke_cluster_compartment_ocid: 358 | type: oci:identity:compartment:id 359 | title: "Existent OKE Cluster Compartment" 360 | description: "The compartment where you find the existent OKE Cluster" 361 | default: compartment_ocid 362 | required: true 363 | visible: 364 | not: 365 | - create_new_oke_cluster 366 | 367 | existent_oke_cluster_id: 368 | type: oci:container:cluster:id 369 | title: "Existent OKE Cluster" 370 | required: true 371 | dependsOn: 372 | compartmentId: existent_oke_cluster_compartment_ocid 373 | visible: 374 | not: 375 | - create_new_oke_cluster 376 | 377 | k8s_version: 378 | type: enum 379 | enum: # Necessary hardcoded supported versions, as ORM does not retrieve the versions from OKE. 380 | - "Latest" 381 | - "v1.19.7" 382 | - "v1.18.10" 383 | - "v1.17.13" 384 | - "v1.16.15" 385 | title: "Kubernetes Version" 386 | required: true 387 | visible: 388 | and: 389 | - create_new_oke_cluster 390 | - show_advanced 391 | 392 | cluster_workers_visibility: 393 | type: enum 394 | enum: 395 | - "Private" 396 | - "Public" 397 | title: "Choose Worker Nodes visibility type" 398 | required: true 399 | visible: 400 | and: 401 | - create_new_oke_cluster 402 | 403 | cluster_endpoint_visibility: 404 | type: enum 405 | enum: 406 | # - "Private" 407 | - "Public" 408 | title: "Choose Kubernetes API Endpoint visibility type" 409 | required: true 410 | visible: 411 | and: 412 | - create_new_oke_cluster 413 | 414 | create_new_compartment_for_oke: 415 | type: boolean 416 | title: "Create new Compartment" 417 | visible: 418 | and: 419 | - create_new_oke_cluster 420 | - show_advanced 421 | 422 | num_pool_workers: 423 | type: integer 424 | title: "Number of Worker Nodes" 425 | minimum: 1 426 | maximum: 1000 427 | required: true 428 | visible: 429 | and: 430 | - create_new_oke_cluster 431 | 432 | node_pool_shape: 433 | type: oci:core:instanceshape:name 434 | title: "Select a shape for the Worker Nodes instances" 435 | required: true 436 | dependsOn: 437 | compartmentId: compartment_ocid 438 | visible: 439 | and: 440 | - create_new_oke_cluster 441 | 442 | node_pool_node_shape_config_ocpus: 443 | type: integer 444 | minimum: 1 445 | maximum: 64 446 | title: "Number of OCPUs" 447 | visible: 448 | and: 449 | - and: 450 | - create_new_oke_cluster 451 | - or: 452 | - eq: 453 | - node_pool_shape 454 | - "VM.Standard.E3.Flex" 455 | - eq: 456 | - node_pool_shape 457 | - "VM.Standard.E4.Flex" 458 | - eq: 459 | - node_pool_shape 460 | - "VM.Standard.A1.Flex" 461 | 462 | node_pool_node_shape_config_memory_in_gbs: 463 | type: integer 464 | minimum: 1 465 | maximum: 1024 466 | title: "Amount of memory (GB)" 467 | visible: 468 | and: 469 | - and: 470 | - create_new_oke_cluster 471 | - or: 472 | - eq: 473 | - node_pool_shape 474 | - "VM.Standard.E3.Flex" 475 | - eq: 476 | - node_pool_shape 477 | - "VM.Standard.E4.Flex" 478 | - eq: 479 | - node_pool_shape 480 | - "VM.Standard.A1.Flex" 481 | 482 | node_pool_name: 483 | type: string 484 | title: "Node Pool Name" 485 | required: true 486 | visible: 487 | and: 488 | - create_new_oke_cluster 489 | - show_advanced 490 | 491 | cluster_options_add_ons_is_kubernetes_dashboard_enabled: 492 | type: boolean 493 | title: "Kubernetes Dashboard Enabled" 494 | visible: false 495 | 496 | generate_public_ssh_key: 497 | type: boolean 498 | title: "Auto generate public ssh key?" 499 | required: true 500 | visible: 501 | and: 502 | - create_new_oke_cluster 503 | - show_advanced 504 | 505 | public_ssh_key: 506 | type: oci:core:ssh:publickey 507 | title: "Import your own SSH public key" 508 | additionalProps: 509 | allowMultiple: true 510 | required: false 511 | 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})( [^,]*)?)*$" 512 | visible: 513 | and: 514 | - and: 515 | - create_new_oke_cluster 516 | - show_advanced 517 | - not: 518 | - generate_public_ssh_key 519 | 520 | image_operating_system: 521 | type: enum 522 | title: "Image OS" 523 | enum: 524 | - "Oracle Linux" 525 | required: true 526 | visible: 527 | and: 528 | - create_new_oke_cluster 529 | - show_advanced 530 | 531 | image_operating_system_version: 532 | type: string 533 | required: true 534 | title: "Image OS Version" 535 | visible: 536 | and: 537 | - create_new_oke_cluster 538 | - show_advanced 539 | 540 | create_dynamic_group_for_nodes_in_compartment: 541 | type: boolean 542 | title: "Create Dynamic Group for Worker Nodes in the Compartment" 543 | required: true 544 | visible: 545 | and: 546 | - show_advanced 547 | 548 | existent_dynamic_group_for_nodes_in_compartment: 549 | type: string 550 | required: true 551 | title: "Existent Dynamic Group" 552 | visible: 553 | and: 554 | - and: 555 | - show_advanced 556 | - or: 557 | - create_compartment_policies 558 | - create_tenancy_policies 559 | - not: 560 | - create_dynamic_group_for_nodes_in_compartment 561 | 562 | create_compartment_policies: 563 | type: boolean 564 | title: "Create Compartment Policies" 565 | required: true 566 | visible: 567 | and: 568 | - show_advanced 569 | 570 | create_tenancy_policies: 571 | type: boolean 572 | title: "Create Tenancy Policies" 573 | required: true 574 | visible: 575 | and: 576 | - show_advanced 577 | 578 | 579 | # Encryption options 580 | use_encryption_from_oci_vault: 581 | type: boolean 582 | title: "Encrypt using Customer-Managed Keys instead of Oracle Managed Encryption" 583 | visible: 584 | and: 585 | - create_new_oke_cluster 586 | - show_advanced 587 | 588 | create_new_encryption_key: 589 | type: boolean 590 | title: "Create new Vault and Key" 591 | visible: 592 | and: 593 | - create_new_oke_cluster 594 | - show_advanced 595 | - use_encryption_from_oci_vault 596 | 597 | existent_encryption_key_id: 598 | type: string 599 | title: "Existent Encryption Key OCID" 600 | required: true 601 | visible: 602 | and: 603 | - and: 604 | - create_new_oke_cluster 605 | - show_advanced 606 | - use_encryption_from_oci_vault 607 | - not: 608 | - create_new_encryption_key 609 | 610 | create_vault_policies_for_group: 611 | type: boolean 612 | title: "Create policies for the user group to manage vault and keys" 613 | visible: 614 | and: 615 | - create_new_oke_cluster 616 | - show_advanced 617 | - use_encryption_from_oci_vault 618 | - create_new_encryption_key 619 | 620 | user_admin_group_for_vault_policy: 621 | type: string 622 | title: "Specify your group to include the policy" 623 | visible: 624 | and: 625 | - create_new_oke_cluster 626 | - show_advanced 627 | - use_encryption_from_oci_vault 628 | - create_new_encryption_key 629 | - create_vault_policies_for_group 630 | 631 | 632 | -------------------------------------------------------------------------------- /devops_oke/tags.tf: -------------------------------------------------------------------------------- 1 | ## Copyright © 2021, 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_id 11 | description = "ArchitectureCenterTagNamespace" 12 | name = "ArchitectureCenter\\devops_oke-${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", "1.2.1"] 28 | } 29 | 30 | provisioner "local-exec" { 31 | command = "sleep 120" 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /devops_oke/terraform.tfvars.example: -------------------------------------------------------------------------------- 1 | # Authentication 2 | tenancy_ocid = "ocid1.tenancy.oc1.." 3 | user_ocid = "ocid1.user.oc1.." 4 | fingerprint = "1c.." 5 | private_key_path = "~/.oci/oci_api_key.pem" 6 | 7 | # Region 8 | region = "us-ashburn-1" 9 | 10 | # Compartment 11 | compartment_id = "ocid1.compartment.oc1." 12 | -------------------------------------------------------------------------------- /devops_oke/tls.tf: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. 2 | # Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. 3 | # 4 | resource "tls_private_key" "public_private_key_pair" { 5 | algorithm = "RSA" 6 | } 7 | -------------------------------------------------------------------------------- /devops_oke/variables.tf: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2021, 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 "user_ocid" {} 6 | variable "fingerprint" {} 7 | variable "private_key_path" {} 8 | variable "region" {} 9 | variable "compartment_id" {} 10 | 11 | 12 | variable "app_name" { 13 | default = "DevOps" 14 | description = "Application name. Will be used as prefix to identify resources, such as OKE, VCN, DevOps, and others" 15 | } 16 | 17 | variable "release" { 18 | description = "Reference Architecture Release (OCI Architecture Center)" 19 | default = "1.2.1" 20 | } 21 | 22 | 23 | --------------------------------------------------------------------------------