public gcpIamCustomRole()
 {
     gcpConfig            = new Config("gcp");
     this.roleId          = gcpConfig.Require("RoleId");
     this.roleTitle       = gcpConfig.Require("RoleTitle");
     this.rolePermissions = gcpConfig.GetObject <string[]>("RolePermissions");
     this.roleDescription = $"{gcpConfig.Require("RoleDescription")}";
     ProvisionRole();
 }
        public ActiveDirectoryResource(Output <string> currentUserObjectId)
        {
            var config = new Config("azureactivedirectory");

            ClientId             = config.Require("clientid");
            ClientSecret         = config.GetSecret("clientsecret");
            Domain               = config.Require("domain");
            TenantId             = config.Require("tenantId");
            _currentUserObjectId = currentUserObjectId;
        }
Esempio n. 3
0
        public KanbernetesStack()
        {
            var config = new Config();

            var azureResources = CreateBaseAzureInfrastructure(config);

            var clusterOptions = new ClusterOptions
            {
                Domain    = config.Require("domain"),
                Namespace = config.Require("kubernetes-namespace"),
                CertificateIssuerAcmeEmail = config.Require("certmanager-acme-email")
            };

            ConfigureKubernetesCluster(azureResources, clusterOptions);
        }
Esempio n. 4
0
    public AzureStack()
    {
        var config   = new Pulumi.Config();
        var deployTo = config.Require("DeployTo");

        // Create an Azure Resource Group
        var resourceGroupName = $"rg-ne-rpc-demo-{deployTo}";
        var resourceGroup     = new ResourceGroup(
            resourceGroupName,
            new ResourceGroupArgs
        {
            Name = resourceGroupName
        });

        // Create an Azure Storage Account
        var storageAccount = new Account($"nerpcdemo{deployTo}", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        // Export the connection string for the storage account
        this.StorageAccountName = storageAccount.Name;
    }
Esempio n. 5
0
    static Task <int> Main() => Deployment.RunAsync(async() => {
        // Fetch the Docker Hub auth info from config.
        var config   = new Pulumi.Config();
        var username = config.Require("dockerUsername");
        var password = config.RequireSecret("dockerPassword");

        // Populate the registry info (creds and endpoint).
        var imageName    = $"{username}/myapp";
        var registryInfo = new ImageRegistry
        {
            Server   = "docker.io",
            Username = username,
            Password = password,
        };

        // Build and publish the app image.
        var image = new Image("my-image", new ImageArgs
        {
            ImageName = username + "/myapp",
            Build     = new DockerBuild {
                Context = "app"
            },
            Registry = registryInfo,
        });

        // Export the resulting image name.
        return(new Dictionary <string, object>
        {
            { "imageName", image.ImageName },
        });
    });
    private void ProvisionRole()
    {
        switch (gcpConfig.Require("RoleScope").ToLower())
        {
        case "project":
        {
            var projIamCustomRole = new Projects.IAMCustomRole("projIamCustomRole",
                                                               new Projects.IAMCustomRoleArgs
                {
                    Description = roleDescription,
                    Permissions = rolePermissions,
                    Project     = gcpConfig.Require("project"),
                    RoleId      = roleId,
                    Title       = roleTitle,
                }
                                                               /// To import an existing role uncomment the following block, update PROJECT_ID AND ROLE_ID then
                                                               /// run Pulumi Up, details, verify property alignment for import, run Pulumi Up, yes, recomment this block
                                                               // ,new CustomResourceOptions {
                                                               //    ImportId = "projects/[PROJECT_ID]/roles/[ROLE_ID]"
                                                               // }
                                                               );
            break;
        }

        default:
        {
            var orgIamCustomRole = new Organizations.IAMCustomRole("orgIamCustomRole",
                                                                   new Organizations.IAMCustomRoleArgs
                {
                    Description = roleDescription,
                    Permissions = rolePermissions,
                    OrgId       = gcpConfig.Require("orgid"),
                    RoleId      = roleId,
                    Title       = roleTitle,
                }
                                                                   /// To import an existing role uncomment the following block, update ORG_ID AND ROLE_ID
                                                                   // ,new CustomResourceOptions {
                                                                   //     ImportId = "organizations/[ORG_ID]/roles/[ROLE_ID]"
                                                                   // }
                                                                   );
            break;
        }
        }
    }
Esempio n. 7
0
    public CreateRoleStack()
    {
        var config = new Pulumi.Config();
        var unprivilegedUsername = config.Require("unprivilegedUsername");

        var unprivilegedUser = new Iam.User("unprivilegedUser", new Iam.UserArgs
        {
            Name = unprivilegedUsername,
        });

        var unprivilegedUserCreds = new Iam.AccessKey("unprivileged-user-key", new Iam.AccessKeyArgs
        {
            User = unprivilegedUser.Name,
        },
                                                      // additional_secret_outputs specify properties that must be encrypted as secrets
                                                      // https://www.pulumi.com/docs/intro/concepts/programming-model/#additionalsecretoutputs
                                                      new CustomResourceOptions {
            AdditionalSecretOutputs = { "secret" }
        });

        var tempPolicy = unprivilegedUser.Arn.Apply((string arn) =>
        {
            AssumeRolePolicyArgs policyArgs = new AssumeRolePolicyArgs(arn);
            return(JsonSerializer.Serialize <AssumeRolePolicyArgs>(policyArgs));
        });

        var allowS3ManagementRole = new Iam.Role("allow-s3-management", new Iam.RoleArgs
        {
            Description      = "Allow management of S3 buckets",
            AssumeRolePolicy = tempPolicy
        });

        var rolePolicy = new Iam.RolePolicy("allow-s3-management-policy", new Iam.RolePolicyArgs
        {
            Role   = allowS3ManagementRole.Name,
            Policy =
                @"{
                ""Version"": ""2012-10-17"",
                ""Statement"": [{
                    ""Effect"": ""Allow"",
                    ""Action"": ""s3:*"",
                    ""Resource"": ""*"",
                    ""Sid"": ""allowS3Access""
                }]
            }"
        },
                                            new CustomResourceOptions {
            Parent = allowS3ManagementRole
        }
                                            );

        this.roleArn         = allowS3ManagementRole.Arn;
        this.accessKeyId     = unprivilegedUserCreds.Id;
        this.secretAccessKey = unprivilegedUserCreds.Secret;
    }
        public PetDoctorStack()
        {
            var config = new Config();

            var azureResources = CreateBaseAzureInfrastructure(config);

            var clusterOptions = new PetDoctorClusterOptions
            {
                Domain    = config.Require("domain"),
                Namespace = config.Require("kubernetes-namespace"),
                CertificateIssuerAcmeEmail = config.Require("certmanager-acme-email"),
                AppointmentApi             = new ReplicaSetConfiguration
                {
                    AadPodIdentityBindingName = "appointments-api-pod-identity-binding",
                    AadPodIdentityName        = "appointments-api-pod-identity",
                    AadPodIdentitySelector    = "appointments-api",
                    DeploymentName            = "appointments-api",
                    IngressName  = "appointments-api-ingress",
                    ServiceName  = "appointments-api-svc",
                    Image        = azureResources.Registry.LoginServer.Apply(loginServer => $"{loginServer}/pet-doctor/appointments/api:{config.Require("versions-appointments-api")}"),
                    Port         = 80,
                    ReplicaCount = 2,
                    Cpu          = new ResourceLimit
                    {
                        Request = "25m",
                        Limit   = "50m"
                    },
                    Memory = new ResourceLimit
                    {
                        Request = "250Mi",
                        Limit   = "400Mi"
                    },
                    SecretName = "appointments-api-secrets"
                }
            };

            ConfigureKubernetesCluster(azureResources, clusterOptions);

            var appointmentApiAzureResources = CreateAppointmentApiAzureResources(azureResources, config, clusterOptions.AppointmentApi.Image);

            SetupAppointmentApiInKubernetes(azureResources, appointmentApiAzureResources, clusterOptions);
        }
Esempio n. 9
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() => {
            var config = new Pulumi.Config();
            var companyCode = config.Require("company_code");
            var location = config.Require("location");
            var environment = config.Require("environment");
            ResourceFactory factory = new ResourceFactory(companyCode, location, environment);

            // Create an Azure Resource Group
            var resourceGroup = factory.GetResourceGroup("00");

            // Create an Azure Storage Account
            var storageAccount = factory.GetStorageAccount("00", resourceGroup.Name);

            // Export the connection string for the storage account
            return new Dictionary <string, object?>
            {
                { "connectionString", storageAccount.PrimaryConnectionString },
            };
        }));
    }
Esempio n. 10
0
    public MyStack()
    {
        var config = new Pulumi.Config();
        var zoneId = config.Require("zone_id");

        var foobar = new Cloudflare.Record("foobar", new Cloudflare.RecordArgs
        {
            Name   = "my-record-csharp",
            ZoneId = zoneId,
            Value  = "162.168.0.14",
            Type   = "A",
            Ttl    = 3600,
        });
    }
Esempio n. 11
0
    public KeyVaultStack()
    {
        // Get current Subscription
        var currentSubscription = Output.Create(GetSubscription.InvokeAsync());
        var tenantId            = currentSubscription.Apply(currentSubscription => currentSubscription.TenantId);

        // Get current Client Config
        var currentClient = Output.Create(GetClientConfig.InvokeAsync());
        var objectId      = currentClient.Apply(currentClient => currentClient.ObjectId);

        var config            = new Pulumi.Config();
        var resourceGroupName = config.Require("resource_group_name");
        var keyVaultName      = config.Require("key_vault_name");

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup(resourceGroupName);

        // Create an Azure Key Vault
        var keyVault = new KeyVault(keyVaultName, new KeyVaultArgs
        {
            ResourceGroupName = resourceGroup.Name,
            SkuName           = "standard",
            TenantId          = tenantId,
            AccessPolicies    =
            {
                new KeyVaultAccessPolicyArgs
                {
                    TenantId          = tenantId,
                    ObjectId          = objectId,
                    SecretPermissions ={ "list",                         "get" }
                }
            }
        });

        this.VaultUri = keyVault.VaultUri;
    }
Esempio n. 12
0
 public AssumeRoleStack()
 {
     var awsConfig       = new Pulumi.Config("aws");
     var config          = new Pulumi.Config();
     var roleToAssumeARN = config.Require("roleToAssumeARN");
     var provider        = new Aws.Provider("privileged", new Aws.ProviderArgs
     {
         AssumeRole = new Aws.Inputs.ProviderAssumeRoleArgs
         {
             RoleArn     = roleToAssumeARN,
             SessionName = "PulumiSession",
             ExternalId  = "PulumiApplication"
         },
         Region = awsConfig.Require("region"),
     });
     var bucket = new Aws.S3.Bucket("myBucket", null, new CustomResourceOptions {
         Provider = provider
     });
 }
Esempio n. 13
0
    public MyStack()
    {
        var config   = new Pulumi.Config();
        var location = config.Get("location") ?? "WestUS";

        var resourceGroup = new ResourceGroup("resourceGroup", new ResourceGroupArgs
        {
            ResourceGroupName = "synapse-rg",
            Location          = location
        });

        var storageAccount = new StorageAccount("storageAccount", new StorageAccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            Location               = resourceGroup.Location,
            AccountName            = "synapsesa",
            AccessTier             = "Hot",
            EnableHttpsTrafficOnly = true,
            IsHnsEnabled           = true,
            Kind = "StorageV2",
            Sku  = new SkuArgs
            {
                Name = "Standard_RAGRS"
            },
        });
        var dataLakeStorageAccountUrl = Output.Format($"https://{storageAccount.Name}.dfs.core.windows.net");

        var users = new BlobContainer("users", new BlobContainerArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AccountName       = storageAccount.Name,
            ContainerName     = "users",
            PublicAccess      = "None"
        });

        var workspace = new Workspace("workspace", new WorkspaceArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            Location               = resourceGroup.Location,
            WorkspaceName          = "my-workspace",
            DefaultDataLakeStorage = new DataLakeStorageAccountDetailsArgs
            {
                AccountUrl = dataLakeStorageAccountUrl,
                Filesystem = "users"
            },
            Identity = new ManagedIdentityArgs
            {
                Type = "SystemAssigned"
            },
            SqlAdministratorLogin         = "******",
            SqlAdministratorLoginPassword = "******"
        });

        var allowAll = new IpFirewallRule("allowAll", new IpFirewallRuleArgs
        {
            ResourceGroupName = resourceGroup.Name,
            WorkspaceName     = workspace.Name,
            RuleName          = "allowAll",
            EndIpAddress      = "255.255.255.255",
            StartIpAddress    = "0.0.0.0"
        });

        var subscriptionId   = resourceGroup.Id.Apply(id => id.Split('/')[2]);
        var roleDefinitionId = $"/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe";

        var storageAccess = new RoleAssignment("storageAccess", new RoleAssignmentArgs
        {
            RoleAssignmentName = new RandomUuid("roleName").Result,
            Scope            = storageAccount.Id,
            PrincipalId      = workspace.Identity.Apply(identity => identity.PrincipalId).Apply(v => v ?? "<preview>"),
            PrincipalType    = "ServicePrincipal",
            RoleDefinitionId = roleDefinitionId
        });
        var userAccess = new RoleAssignment("userAccess", new RoleAssignmentArgs
        {
            RoleAssignmentName = new RandomUuid("userRoleName").Result,
            Scope            = storageAccount.Id,
            PrincipalId      = config.Require("userObjectId"),
            PrincipalType    = "User",
            RoleDefinitionId = roleDefinitionId
        });

        var sqlPool = new SqlPool("sqlPool", new SqlPoolArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Location          = resourceGroup.Location,
            WorkspaceName     = workspace.Name,
            SqlPoolName       = "SQLPOOL1",
            Collation         = "SQL_Latin1_General_CP1_CI_AS",
            CreateMode        = "Default",
            Sku = new Pulumi.AzureNextGen.Synapse.V20190601Preview.Inputs.SkuArgs
            {
                Name = "DW100c"
            },
        });

        var sparkPool = new BigDataPool("sparkPool", new BigDataPoolArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Location          = resourceGroup.Location,
            WorkspaceName     = workspace.Name,
            BigDataPoolName   = "Spark1",
            AutoPause         = new AutoPausePropertiesArgs
            {
                DelayInMinutes = 15,
                Enabled        = true,
            },
            AutoScale = new AutoScalePropertiesArgs
            {
                Enabled      = true,
                MaxNodeCount = 3,
                MinNodeCount = 3,
            },
            NodeCount      = 3,
            NodeSize       = "Small",
            NodeSizeFamily = "MemoryOptimized",
            SparkVersion   = "2.4"
        });
    }
Esempio n. 14
0
    public MyStack()
    {
        var config = new Pulumi.Config();

        // Per-cluster config
        var aksClusterConfigs = new[] {
            new {
                Name      = "east",
                Location  = "eastus",
                NodeCount = 2,
                NodeSize  = ContainerServiceVMSizeTypes.Standard_D2_v2,
            },
            new {
                Name      = "west",
                Location  = "westus",
                NodeCount = 5,
                NodeSize  = ContainerServiceVMSizeTypes.Standard_D2_v2,
            },
        };

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("aks", new ResourceGroupArgs
        {
            Location = config.Get("location") ?? "eastus",
        });

        // Create the AD service principal for the K8s cluster.
        var adApp = new Application("aks", new ApplicationArgs
        {
            DisplayName = "my-aks-multicluster",
        });
        var adSp = new ServicePrincipal("aksSp", new ServicePrincipalArgs
        {
            ApplicationId = adApp.ApplicationId
        });
        var adSpPassword = new ServicePrincipalPassword("aksSpPassword", new ServicePrincipalPasswordArgs
        {
            ServicePrincipalId = adSp.Id,
            Value   = config.Require("password"),
            EndDate = "2099-01-01T00:00:00Z",
        });

        // Create the individual clusters
        var aksClusterNames = new List <Output <string> >();

        foreach (var perClusterConfig in aksClusterConfigs)
        {
            var cluster = new ManagedCluster($"aksCluster-{perClusterConfig.Name}", new ManagedClusterArgs
            {
                // Global config arguments
                ResourceGroupName = resourceGroup.Name,
                LinuxProfile      = new ContainerServiceLinuxProfileArgs
                {
                    AdminUsername = "******",
                    Ssh           = new ContainerServiceSshConfigurationArgs
                    {
                        PublicKeys =
                        {
                            new ContainerServiceSshPublicKeyArgs
                            {
                                KeyData = config.Require("sshPublicKey"),
                            }
                        }
                    }
                },
                ServicePrincipalProfile = new ManagedClusterServicePrincipalProfileArgs
                {
                    ClientId = adApp.ApplicationId,
                    Secret   = adSpPassword.Value
                },

                // Per-cluster config arguments
                Location          = perClusterConfig.Location,
                AgentPoolProfiles =
                {
                    new ManagedClusterAgentPoolProfileArgs
                    {
                        Mode   = AgentPoolMode.System,
                        Name   = "agentpool",
                        Count  = perClusterConfig.NodeCount,
                        VmSize = perClusterConfig.NodeSize,
                    }
                },
                DnsPrefix         = $"{Pulumi.Deployment.Instance.StackName}-kube",
                KubernetesVersion = "1.18.14",
            });

            aksClusterNames.Add(cluster.Name);
        }
        ;

        this.aksClusterNames = Output.All(aksClusterNames);
    }
Esempio n. 15
0
    public BotStack()
    {
        var config  = new Pulumi.Config();
        var botName = config.Require("botName");

        var resourceGroup = new ResourceGroup("botservice-rg");

        var storageAccount = new Storage.Account("sa", new Storage.AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        var appServicePlan = new Plan("asp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "App",
            Sku  = new PlanSkuArgs
            {
                Tier = "Basic",
                Size = "B1"
            }
        });

        var container = new Storage.Container("zips", new Storage.ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
        });

        var blob = new Storage.Blob("zip", new Storage.BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("bot/publish")
        });

        var codeBlobUrl = Storage.SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var appInsights = new Insights("ai", new InsightsArgs
        {
            ApplicationType   = "web",
            ResourceGroupName = resourceGroup.Name
        });

        var appInsightApiKey = new ApiKey("ai", new ApiKeyArgs
        {
            ApplicationInsightsId = appInsights.Id,
            ReadPermissions       = "api",
        });

        var luis = new Cognitive.Account("cs", new Cognitive.AccountArgs
        {
            Kind = "CognitiveServices", // includes LUIS
            ResourceGroupName = resourceGroup.Name,
            SkuName           = "S0"
        });

        var msa = new Application("msapp", new ApplicationArgs
        {
            Oauth2AllowImplicitFlow = false,
            AvailableToOtherTenants = true,
            PublicClient            = true
        });

        var pwd = new RandomPassword("password", new RandomPasswordArgs
        {
            Length     = 16,
            MinNumeric = 1,
            MinSpecial = 1,
            MinUpper   = 1,
            MinLower   = 1
        });

        var msaSecret = new ApplicationPassword("msasecret", new ApplicationPasswordArgs
        {
            ApplicationObjectId = msa.ObjectId,
            EndDateRelative     = "8640h",
            Value = pwd.Result
        });

        var app = new AppService("app", new AppServiceArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl           },
                { "MicrosoftAppId",           msa.ApplicationId     },
                { "MicrosoftAppPassword",     msaSecret.Value       },
                { "LuisApiKey",               luis.PrimaryAccessKey },
            },
            HttpsOnly = true
        });

        var bot = new WebApp(botName, new WebAppArgs
        {
            DisplayName       = botName,
            MicrosoftAppId    = msa.ApplicationId,
            ResourceGroupName = resourceGroup.Name,
            Sku      = "F0",
            Location = "global",
            Endpoint = Output.Format($"https://{app.DefaultSiteHostname}/api/messages"),
            DeveloperAppInsightsApiKey        = appInsightApiKey.Key,
            DeveloperAppInsightsApplicationId = appInsights.AppId,
            DeveloperAppInsightsKey           = appInsights.InstrumentationKey
        });

        this.BotEndpoint          = bot.Endpoint;
        this.MicrosoftAppId       = msa.ApplicationId;
        this.MicrosoftAppPassword = msaSecret.Value;
    }
Esempio n. 16
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(async() => {
            var config = new Pulumi.Config();
            var environment = config.Require("environment");
            var companyCode = config.Require("company_code");
            var scope = config.Require("default_scope");
            var location = config.Require("location");
            var webAppPath = config.Require("webAppPath");
            var sourcePath = config.Require("sourcePath");
            ResourceFactory factory = new ResourceFactory(companyCode, location, environment, scope);

            Dictionary <string, string> scopeTag = new Dictionary <string, string>();
            scopeTag.Add("scope", scope);

            // Create a resource group
            var resourceGroup = factory.GetResourceGroup(tags: scopeTag);

            // Create a storage account for Blobs
            var storageAccount = factory.GetStorageAccount("Standard", "LRS", resourceGroup.Name, tags: scopeTag);

            // The container to put our files into
            var storageContainer = factory.GetContainer(storageAccountName: storageAccount.Name);

            // Azure SQL Server that we want to access from the application
            var administratorLoginPassword = factory.GetRandomPassword(length: 16).Result;
            var sqlServer = factory.GetSqlServer(resourceGroupName: resourceGroup.Name, administratorLogin: "******",
                                                 administratorLoginPassword: administratorLoginPassword, version: "12.0", tags: scopeTag);

            // Azure SQL Database that we want to access from the application
            var database = factory.GetDatabase(resourceGroupName: resourceGroup.Name, sqlServerName: sqlServer.Name, requestedServiceObjectiveName: "S0", tags: scopeTag);

            // The connection string that has no credentials in it: authertication will come through MSI
            var connectionString = Output.Format($"Server=tcp:{sqlServer.Name}.database.windows.net;Database={database.Name};");

            // A file in Blob Storage that we want to access from the application
            var textBlob = factory.GetBlob(storageAccountName: storageAccount.Name, storageContainerName: storageContainer.Name, type: "block", source: sourcePath);

            // A plan to host the App Service
            var appServicePlanSku = factory.GetPlanSku(tier: "Basic", size: "B1");
            var appServicePlan = factory.GetPlan(resourceGroupName: resourceGroup.Name, sku: appServicePlanSku, kind: "App", tags: scopeTag);

            // ASP.NET deployment package
            var content = new FileArchive(webAppPath);
            var blob = factory.GetZipBlob(storageAccountName: storageAccount.Name, storageContainerName: storageContainer.Name, type: "block", content: content);

            var clientConfig = await Pulumi.Azure.Core.Invokes.GetClientConfig();
            var tenantId = clientConfig.TenantId;
            var currentPrincipal = clientConfig.ObjectId;

            // Key Vault to store secrets (e.g. Blob URL with SAS)
            var vaultAccessPolicies = factory.GetKeyVaultAccessPolicy(tenantId: Output.Create(tenantId), objectId: Output.Create(currentPrincipal),
                                                                      secretPermissions: new List <string> {
                "delete", "get", "list", "set"
            });
            var vault = factory.GetKeyVault(resourceGroupName: resourceGroup.Name, tenantId: Output.Create(tenantId), accessPolicies: vaultAccessPolicies, tags: scopeTag);

            // Put the URL of the zip Blob to KV
            var secret = factory.GetSecret(keyVaultId: vault.Id, blob: blob, storageAccount: storageAccount, tags: scopeTag);
            var secretUri = Output.Format($"{secret.VaultUri}secrets/{secret.Name}/{secret.Version}");

            // The application hosted in App Service
            var app = factory.GetAppService(resourceGroupName: resourceGroup.Name, appServicePlanId: appServicePlan.Id, blobUrl: textBlob.Url, secretUri: secretUri,
                                            connectionString: connectionString, connectionStringName: "db", connectionStringType: "SQLAzure", tags: scopeTag);

            // Work around a preview issue https://github.com/pulumi/pulumi-azure/issues/192
            var principalId = app.Identity.Apply(id => id.PrincipalId ?? "11111111-1111-1111-1111-111111111111");

            // Grant App Service access to KV secrets
            var policy = factory.GetAccessPolicy(keyVaultId: vault.Id, tenantId: Output.Create(tenantId), objectId: principalId,
                                                 secretPermissions: new List <string> {
                "get"
            });

            // Make the App Service the admin of the SQL Server (double check if you want a more fine-grained security model in your real app)
            var sqlAdmin = factory.GetActiveDirectoryAdministrator(resourceGroupName: resourceGroup.Name, tenantId: Output.Create(tenantId), objectId: principalId,
                                                                   loginUsername: "******", sqlServerName: sqlServer.Name);

            // Grant access from App Service to the container in the storage
            var blobPermission = factory.GetAssignment(principalId: principalId, storageAccountId: storageAccount.Id, storageContainerName: storageContainer.Name,
                                                       roleDefinitionName: "Storage Blob Data Reader");

            // Add SQL firewall exceptions
            var firewallRules = app.OutboundIpAddresses.Apply(
                ips => ips.Split(",").Select(ip => factory.GetFirewallRule(resourceGroupName: resourceGroup.Name, startIpAddress: ip, endIpAddress: ip, sqlServerName: sqlServer.Name)).ToList());

            return new Dictionary <string, object?>
            {
                { "endpoint", Output.Format($"https://{app.DefaultSiteHostname}") },
            };
        }));
    }
Esempio n. 17
0
    public DeploymentStack()
    {
        // Define variables
        var config             = new Pulumi.Config();
        var rgName             = string.Format("{0}-{1}-{2}-{3}", config.Require("prefix"), config.Require("resourceFunction"), config.Require("environment"), config.Require("azureRegion"));
        var storageAccountName = string.Format("{0}{1}sa{2}{3}", config.Require("prefix"), config.Require("resourceFunction"), config.Require("environment"), config.Require("azureRegion"));
        var apimName           = string.Format("{0}-{1}-{2}-{3}", config.Require("prefix"), config.Require("resourceFunction"), config.Require("environment"), config.Require("azureRegion"));
        var kvName             = string.Format("{0}-{1}-kv-{2}-{3}", config.Require("prefix"), config.Require("resourceFunction"), config.Require("environment"), config.Require("azureRegion"));
        var appInsightsName    = string.Format("{0}-{1}-appinsights-{2}-{3}", config.Require("prefix"), config.Require("resourceFunction"), config.Require("environment"), config.Require("azureRegion"));
        var tags = new InputMap <string>()
        {
            { "belongsto", "Core Resources" },
            { "environment", "Development" },
            { "costcenter", "Backend" },
            { "owner", "IT" }
        };

        // Get current identity details
        var clientConfig     = Output.Create(Pulumi.Azure.Core.Invokes.GetClientConfig());
        var tenantId         = clientConfig.Apply(c => c.TenantId);
        var currentPrincipal = clientConfig.Apply(c => c.ObjectId);

        // Create the Azure Resource Group
        var rg = new ResourceGroup("rg", new ResourceGroupArgs()
        {
            Name     = rgName,
            Location = config.Require("azureLocation"),
            Tags     = tags
        });

        // Create the storage account to contain policy, OpenApi and other deployment related files
        var sa = new Account("sa", new AccountArgs
        {
            ResourceGroupName = rg.Name,
            Name                   = storageAccountName,
            AccountKind            = "StorageV2",
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
            EnableHttpsTrafficOnly = true,
            Tags                   = tags
        },
                             new CustomResourceOptions()
        {
            DependsOn = { rg }
        });
        var saContainerApim = new Container("apim-files",
                                            new ContainerArgs()
        {
            StorageAccountName = sa.Name, ContainerAccessType = "private"
        },
                                            new CustomResourceOptions()
        {
            DependsOn = { rg }
        });

        var saContainerApi = new Container("api-files",
                                           new ContainerArgs()
        {
            StorageAccountName = sa.Name, ContainerAccessType = "private"
        },
                                           new CustomResourceOptions()
        {
            DependsOn = { rg }
        });

        // Create key vault to contain the certificate secret
        var kv = new KV.KeyVault("kv", new KV.KeyVaultArgs()
        {
            Name = kvName,
            ResourceGroupName        = rg.Name,
            EnabledForDiskEncryption = false,
            SkuName        = "standard",
            TenantId       = tenantId,
            AccessPolicies =
            {
                new KeyVaultAccessPoliciesArgs
                {
                    TenantId               = tenantId,
                    ObjectId               = currentPrincipal,
                    SecretPermissions      = { "get" },
                    CertificatePermissions ={ "delete", "create", "get", "import", "list", "update" },
                }
            },
            Tags = tags
        });

        // Upload the certificate to Key Vault --> Currently disabled because no valid pfx which breaks the deployment
        // var pfxBytes = System.IO.File.ReadAllBytes("certificates/"+ config.Require("customDomainsCertificateName"));
        // var cert = new KV.Certificate("apim-tls-certificate", new KV.CertificateArgs()
        // {
        //     Name = "apim-tls-certificate",
        //     KeyVaultId = kv.Id,
        //     KeyVaultCertificate = new CertificateCertificateArgs()
        //     {
        //         Contents = System.Convert.ToBase64String(pfxBytes),
        //         Password = config.Require("customDomainsCertificatePasword")
        //     },
        //     CertificatePolicy = new CertificateCertificatePolicyArgs()
        //     {
        //         IssuerParameters = new CertificateCertificatePolicyIssuerParametersArgs()
        //         {
        //             Name = config.Require("customDomainsCertificateIssuer")
        //         },
        //         KeyProperties = new CertificateCertificatePolicyKeyPropertiesArgs()
        //         {
        //             Exportable = true,
        //             KeySize = 2048,
        //             KeyType = "RSA",
        //             ReuseKey = false
        //         },
        //         SecretProperties = new CertificateCertificatePolicySecretPropertiesArgs()
        //         {
        //             ContentType = "application/x-pkcs12"
        //         }
        //     }
        // },
        // new CustomResourceOptions()
        // {
        //     DependsOn = { rg, kv }
        // });

        // APIM resource
        var apim = new Service("apim", new ServiceArgs()
        {
            Name = apimName,
            ResourceGroupName = rg.Name,
            SkuName           = "Developer_1",
            PublisherEmail    = config.Require("publisherEmail"),
            PublisherName     = config.Require("publisherName"),
            Tags     = tags,
            Identity = new ServiceIdentityArgs()
            {
                Type = "SystemAssigned"
            }
        },
                               new CustomResourceOptions()
        {
            CustomTimeouts = new CustomTimeouts {
                Create = TimeSpan.FromMinutes(60)
            },
            DependsOn = { rg, sa, kv }
        });

        // Change Key Vault policy to be able to have APIM access the certificate
        // var kvApimPolicy = new KV.AccessPolicy("apim-policy", new KV.AccessPolicyArgs()
        // {
        //     TenantId = tenantId,
        //     ObjectId = apim.Identity.PrincipalId,
        //     SecretPermissions = {"get"},
        //     CertificatePermissions = {"get", "list"},
        //     KeyVaultId = kv.Id
        // });

        // Set custom domain
        // Call Powershell to assign custom domain to APIM instance

        // Create product on APIM
        var apimProduct = new Product("apimProduct", new ProductArgs()
        {
            ResourceGroupName    = rg.Name,
            ApiManagementName    = apim.Name,
            DisplayName          = config.Require("productName"),
            ProductId            = config.Require("productId"),
            ApprovalRequired     = bool.Parse(config.Require("productApprovalRequired")),
            Published            = bool.Parse(config.Require("productPublished")),
            SubscriptionRequired = bool.Parse(config.Require("productSubscriptionRequired")),
            SubscriptionsLimit   = int.Parse(config.Require("productSubscriptionLimit"))
        },
                                      new CustomResourceOptions()
        {
            DependsOn = { apim }
        });
        var apimProductPolicy = new ProductPolicy("apimProductPolicy", new ProductPolicyArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            ProductId         = config.Require("productId"),
            XmlContent        = @"<policies>
                            <inbound>
                                <base />
                            </inbound>
                            <backend>
                                <base />
                            </backend>
                            <outbound>
                                <set-header name='Server' exists-action='delete' />
                                <set-header name='X-Powered-By' exists-action='delete' />
                                <set-header name='X-AspNet-Version' exists-action='delete' />
                                <base />
                            </outbound>
                            <on-error>
                                <base />
                            </on-error>
                        </policies>"
        },
                                                  new CustomResourceOptions()
        {
            DependsOn = { apim, apimProduct }
        });

        // Create user
        var apimUser = new User("user", new UserArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            UserId            = string.Format("{0}-user", config.Require("productId")),
            Email             = string.Format("{0}-{1}@didago.nl", config.Require("productId"), config.Require("environment")),
            FirstName         = "user",
            LastName          = config.Require("productName"),
            State             = "active"
        },
                                new CustomResourceOptions()
        {
            DependsOn = { apim }
        });

        // Create subscription
        var apimSubscription = new Subscription("subscription", new SubscriptionArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            DisplayName       = "Some subscription",
            ProductId         = apimProduct.Id,
            UserId            = apimUser.Id,
            PrimaryKey        = config.Require("productSubscriptionKey")
        },
                                                new CustomResourceOptions()
        {
            DependsOn = { apim, apimProduct, apimUser }
        });

        // Create Application Insights
        var appInsights = new Insights("appinsights", new InsightsArgs()
        {
            Name = appInsightsName,
            ResourceGroupName = rg.Name,
            ApplicationType   = "web",
            Tags = tags
        });
        // Create APIM diagnostics logger
        var apimLogger = new Logger("apimLogger", new LoggerArgs()
        {
            Name = $"{apimName}-logger",
            ResourceGroupName   = rg.Name,
            ApiManagementName   = apim.Name,
            ApplicationInsights = new LoggerApplicationInsightsArgs()
            {
                InstrumentationKey = appInsights.InstrumentationKey
            }
        },
                                    new CustomResourceOptions()
        {
            DependsOn = { appInsights, apim }
        });

        // Add health probe to APIM, create operation, policy and assign to product
        var apiHealthProbe = new Api("healthProbe", new ApiArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            DisplayName       = "Health probe",
            Path      = "health-probe",
            Protocols = "https",
            Revision  = "1"
        },
                                     new CustomResourceOptions()
        {
            DependsOn = { apim }
        });
        var apimHealthProbeOperation = new ApiOperation("pingOperation", new ApiOperationArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            ApiName           = apiHealthProbe.Name,
            DisplayName       = "Ping",
            Method            = "GET",
            UrlTemplate       = "/",
            OperationId       = "get-ping"
        },
                                                        new CustomResourceOptions()
        {
            DependsOn = { apiHealthProbe }
        });
        var apiHealthProbePolicy = new ApiPolicy("healthProbePolicy", new ApiPolicyArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            ApiName           = apiHealthProbe.Name,
            XmlContent        = @"<policies>
                            <inbound>
                                <return-response>
                                    <set-status code='200' />
                                </return-response>
                                <base />
                            </inbound>
                        </policies>"
        },
                                                 new CustomResourceOptions()
        {
            DependsOn = { apimHealthProbeOperation }
        });
        var apiHealtProbeProduct = new ProductApi("healthProbeProduct", new ProductApiArgs()
        {
            ResourceGroupName = rg.Name,
            ApiManagementName = apim.Name,
            ApiName           = apiHealthProbe.Name,
            ProductId         = apimProduct.ProductId
        },
                                                  new CustomResourceOptions()
        {
            DependsOn = { apim, apimProduct, apiHealthProbePolicy }
        });
    }
Esempio n. 18
0
 private Pipeline CreatePipeline(Bucket bucket, Role pipelineRole, Project buildProject, Role cloudFormationRole)
 {
     Pipeline pipeline = new Pipeline("WakerUpper", new PipelineArgs
     {
         ArtifactStore = new PipelineArtifactStoreArgs
         {
             Type     = "S3",
             Location = bucket.BucketName,
         },
         RoleArn = pipelineRole.Arn,
         Stages  =
         {
             new PipelineStageArgs
             {
                 Name    = "Source",
                 Actions =
                 {
                     new PipelineStageActionArgs
                     {
                         Name          = "Source",
                         Category      = "Source",
                         Owner         = "ThirdParty",
                         Provider      = "GitHub",
                         Version       = "1",
                         Configuration =
                         {
                             { "Owner",                Config.Require("githubOwner")                                               },
                             { "Repo",                 Config.Require("githubRepo")                                                },
                             { "Branch",               Config.Require("githubBranch")                                              },
                             { "OAuthToken",           GitHubConfig.RequireSecret("token")                                         },
                             { "PollForSourceChanges", "false"                                                                     },
                         },
                         OutputArtifacts ={ "SourceArtifact" },
                     },
                 },
             },
             new PipelineStageArgs
             {
                 Name    = "Build",
                 Actions =
                 {
                     new PipelineStageActionArgs
                     {
                         Name           = "Api-Build",
                         Category       = "Build",
                         Owner          = "AWS",
                         Provider       = "CodeBuild",
                         Version        = "1",
                         InputArtifacts ={ "SourceArtifact"                                     },
                         Configuration  =
                         {
                             { "ProjectName", buildProject.Name                     },
                             {
                                 "EnvironmentVariables",
                                 "[ { \"name\": \"ProjectPath\", \"value\": \"WakerUpper.Api\" } ]"
                             },
                         },
                         OutputArtifacts ={ "ApiBuildArtifact"                                   },
                         RunOrder        = 1,
                     },
                     new PipelineStageActionArgs
                     {
                         Name           = "WebApp-Build",
                         Category       = "Build",
                         Owner          = "AWS",
                         Provider       = "CodeBuild",
                         Version        = "1",
                         InputArtifacts ={ "SourceArtifact"                                     },
                         Configuration  =
                         {
                             { "ProjectName", buildProject.Name                     },
                             {
                                 "EnvironmentVariables",
                                 "[ { \"name\": \"ProjectPath\", \"value\": \"WakerUpper.WebApp\" } ]"
                             },
                         },
                         OutputArtifacts ={ "WebAppBuildArtifact"                                },
                         RunOrder        = 1,
                     },
                 },
             },
             new PipelineStageArgs
             {
                 Name    = "Deploy",
                 Actions =
                 {
                     new PipelineStageActionArgs
                     {
                         Name           = "Api-CreateChangeSet",
                         Category       = "Deploy",
                         Owner          = "AWS",
                         Provider       = "CloudFormation",
                         Version        = "1",
                         InputArtifacts ={ "ApiBuildArtifact"                                       },
Esempio n. 19
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(async() => {
            // Get the configuration and required variables
            var config = new Pulumi.Config();
            var location = config.Require("location");
            var companyCode = config.Require("company_code");
            var environment = config.Require("environment");
            var scope = config.Require("default_scope");
            var tenantId = Output.Create <string>(config.Require("tenant_id"));
            var rbacGroups = config.RequireObject <JsonElement>("rbac_groups");
            List <string> rbacGroupsList = new List <string>();
            foreach (JsonElement group in rbacGroups.EnumerateArray())
            {
                rbacGroupsList.Add(group.ToString());
            }

            // Create the factory
            ResourceFactory factory = new ResourceFactory(companyCode, location, environment, scope);

            // Create the tags to be applied to these resources: scope
            Dictionary <string, string> tags = new Dictionary <string, string>();
            tags.Add("scope", scope);

            // Create the resource group, analytics workspace and automation account
            var resourceGroup = factory.GetResourceGroup(tags: tags);
            var workspace = factory.GetAnalyticsWorkspace(resourceGroupName: resourceGroup.Name, tags: tags);
            var automationAccount = factory.GetAutomationAccount(resourceGroupName: resourceGroup.Name, tags: tags);

            #region Runbooks
            // Runbook for UpdatePowershellModules
            DateTime now = DateTime.Now;
            int start = (int)now.DayOfWeek;
            int target = (int)DayOfWeek.Sunday;
            target = (target <= start ? target + 7 : target);
            DateTime nextSunday = now.AddDays(target - start);
            string publishContentLink = "https://raw.githubusercontent.com/Daniel-Jennings/PulumiTemplates/master/sub-tcms-pul-infra/Runbooks/UpdatePowershellModules.ps1";
            string runbookDescription = "A runbook to update all of the Powershell modules used in the automation account. Should be run weekly to ensure latest module code is available";
            string startTime = nextSunday.ToString("yyyy'-'MM'-'dd") + "T20:00:00-04:00";
            string scheduleDescription = "Run a task weekly on Sunday at 8PM";
            Dictionary <string, string> parameters = new Dictionary <string, string> {
                { "resourcegroupname", factory.ResourceNames["rg"][0] },
                { "automationaccountname", factory.ResourceNames["aacc"][0] }
            };
            var updatePowershellModulesRunbook = factory.GetAutomationRunbook(name: "UpdatePowershellModules", resourceGroupName: resourceGroup.Name,
                                                                              automationAccountName: automationAccount.Name, publishContentLink: publishContentLink, description: runbookDescription, runbookType: "PowerShell", tags: tags);
            var updatePowershellModulesSchedule = factory.GetAutomationSchedule(name: "WeeklySunday8PM", resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                                description: scheduleDescription, frequency: "Week", startTime: startTime, timezone: "America/Toronto", interval: 1, weekDays: new List <string> {
                "Sunday"
            });
            var updatePowershellModulesJob = factory.GetAutomationJobSchedule(resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                              runbookName: updatePowershellModulesRunbook.Name, scheduleName: updatePowershellModulesSchedule.Name,
                                                                              parameters: parameters);

            // Runbook for ShutdownSchedule
            DateTime tomorrow = now.AddDays(1);
            publishContentLink = "https://raw.githubusercontent.com/Daniel-Jennings/PulumiTemplates/master/sub-tcms-pul-infra/Runbooks/ShutdownSchedule.ps1";
            runbookDescription = "A runbook to control shutdown / startup schedules for VMs and Scale Sets";
            var shutdownScheduleRunbook = factory.GetAutomationRunbook(name: "ShutdownSchedule", resourceGroupName: resourceGroup.Name,
                                                                       automationAccountName: automationAccount.Name, publishContentLink: publishContentLink, description: runbookDescription, runbookType: "PowerShellWorkflow", tags: tags);

            // Schedule for Startup
            startTime = tomorrow.ToString("yyyy'-'MM'-'dd") + "T07:00:00-04:00";
            scheduleDescription = "Run a task daily at 7AM";
            parameters = new Dictionary <string, string> {
                { "shutdown", "false" },
                { "verboselogging", "false" }
            };
            var shutdownScheduleScheduleStartup = factory.GetAutomationSchedule(name: "Daily7AM", resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                                description: scheduleDescription, frequency: "Day", startTime: startTime, timezone: "America/Toronto", interval: 1);
            var shutdownScheduleJobStartup = factory.GetAutomationJobSchedule(resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                              runbookName: shutdownScheduleRunbook.Name, scheduleName: shutdownScheduleScheduleStartup.Name,
                                                                              parameters: parameters);

            // Schedule for Shutdown
            startTime = tomorrow.ToString("yyyy'-'MM'-'dd") + "T19:00:00-04:00";
            scheduleDescription = "Run a task daily at 7PM";
            parameters = new Dictionary <string, string> {
                { "shutdown", "true" },
                { "verboselogging", "false" }
            };
            var shutdownScheduleScheduleShutdown = factory.GetAutomationSchedule(name: "Daily7PM", resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                                 description: scheduleDescription, frequency: "Day", startTime: startTime, timezone: "America/Toronto", interval: 1);
            var shutdownScheduleJobShutdown = factory.GetAutomationJobSchedule(resourceGroupName: resourceGroup.Name, automationAccountName: automationAccount.Name,
                                                                               runbookName: shutdownScheduleRunbook.Name, scheduleName: shutdownScheduleScheduleShutdown.Name,
                                                                               parameters: parameters);
            #endregion
            // Return any outputs that may be required for subsequent steps
            return new Dictionary <string, object?>
            {
                { "resourceGroupId", resourceGroup.Id },
                { "resourceGroupName", resourceGroup.Name },
                { "workspaceId", workspace.WorkspaceId },
            };
        }));
    }
Esempio n. 20
0
    public AwsStack()
    {
        var config   = new Pulumi.Config();
        var deployTo = config.Require("DeployTo");

        var tags = new InputMap <string>
        {
            { "User:Project", Pulumi.Deployment.Instance.ProjectName },
            { "User:Stack", Pulumi.Deployment.Instance.StackName }
        };

        // Create an AWS resource (S3 Bucket)
        var dataBucket = new Bucket(
            $"ne-rpc-demo-data-{deployTo}",
            new BucketArgs
        {
            Tags = tags
        }
            );

        // Create a role to run the lambda
        var lambdaRole = new Role("lambdaRole", new RoleArgs
        {
            AssumeRolePolicy =
                @"{
                    ""Version"": ""2012-10-17"",
                    ""Statement"": [
                        {
                            ""Action"": ""sts:AssumeRole"",
                            ""Principal"": {
                                ""Service"": ""lambda.amazonaws.com""
                            },
                            ""Effect"": ""Allow"",
                            ""Sid"": """"
                        }
                    ]
                }"
        }
                                  );

        var logPolicy = new RolePolicy("lambdaLogPolicy", new RolePolicyArgs
        {
            Role   = lambdaRole.Id,
            Policy =
                @"{
                ""Version"": ""2012-10-17"",
                ""Statement"": [{
                    ""Effect"": ""Allow"",
                    ""Action"": [
                        ""logs:CreateLogGroup"",
                        ""logs:CreateLogStream"",
                        ""logs:PutLogEvents""
                    ],
                    ""Resource"": ""arn:aws:logs:*:*:*""
                }]
            }"
        });

        var bucketPolicy = new RolePolicy("lambdaBucketPolicy", new RolePolicyArgs
        {
            Role   = lambdaRole.Id,
            Policy =
                Output.Format($@"{{
            ""Version"": ""2012-10-17"",
            ""Statement"": [
                {{
                    ""Effect"": ""Allow"",
                    ""Action"": [
                        ""s3:*""
                    ],
                    ""Resource"": ""{dataBucket.Arn}""
                }},
                {{
                    ""Effect"": ""Allow"",
                    ""Action"": [
                        ""s3:*""
                    ],
                    ""Resource"": ""{dataBucket.Arn}/*""
                }}
            ]
        }}")
        });

        var quoteFetch = new Function(
            "quote-fetch-lambda",
            new FunctionArgs
        {
            Runtime     = "dotnetcore3.1",
            Code        = new FileArchive("../aws-lambda/publish"),
            Handler     = "aws-lambda::Recumbent.Demo.Aws.AwsLambda::FunctionHandler",
            Environment = new FunctionEnvironmentArgs
            {
                Variables = new InputMap <string>
                {
                    { "QuoteServerHost", "https://vn651r8t22.execute-api.eu-west-2.amazonaws.com/Prod" },
                    { "DataBucket", dataBucket.Id },
                }
            },
            Role    = lambdaRole.Arn,
            Timeout = 60,
            Tags    = tags
        }
            );


        // Export useful things
        this.DataBucketName    = dataBucket.Id;
        this.DataBucketArn     = dataBucket.Arn;
        this.FunctionInvokeArn = quoteFetch.InvokeArn;
    }
Esempio n. 21
0
    static Task <int> Main(string[] args)
    {
        return(Pulumi.Deployment.RunAsync(() =>
        {
            var config = new Pulumi.Config();
            var pw = config.RequireSecret("message");
            var rawPw = config.Require("message");

            var cmData = new CoreV1.ConfigMap("cmdata", new ConfigMapArgs
            {
                Data = new InputMap <string>
                {
                    { "password", pw },
                }
            });

            var cmBinaryData = new CoreV1.ConfigMap("cmbinarydata", new ConfigMapArgs
            {
                BinaryData = new InputMap <string>
                {
                    { "password", pw.Apply(v => Base64Encode(v)) },
                }
            });

            var sStringData = new CoreV1.Secret("sstringdata", new SecretArgs
            {
                StringData = new InputMap <string>
                {
                    { "password", rawPw }
                }
            });

            var sData = new CoreV1.Secret("sdata", new SecretArgs
            {
                Data = new InputMap <string>
                {
                    { "password", Base64Encode(rawPw) }
                }
            });

            var name = $"test-{RandomString()}";
            var secretYAML = $@"
apiVersion: v1
kind: Secret
metadata:
  name: {name}
stringData:
  password: {rawPw}
";
            var cg = new Yaml.ConfigGroup("example", new Yaml.ConfigGroupArgs
            {
                Yaml = secretYAML
            });
            var cgSecret = cg.GetResource <CoreV1.Secret>(name);

            return new Dictionary <string, object>
            {
                { "cmData", cmData.Data },
                { "cmBinaryData", cmData.BinaryData },
                { "sStringData", sStringData.StringData },
                { "sData", sStringData.Data },
                { "cgData", cgSecret.Apply(v => v.Data) },
            };
        }));
    }
Esempio n. 22
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() => {
            var config = new Pulumi.Config();
            var subscriptionId = config.Require("subscriptionId");

            var azureADGroup = new Group(
                "AzureUsersGroup",
                new GroupArgs {
                Name = "All Azure Users"
            });

            var role = new RoleDefinition(
                "Role",
                new RoleDefinitionArgs
            {
                Name = "Register Azure resource providers",
                Description = "Can register Azure resource providers",
                Permissions = new RoleDefinitionPermissionsArgs {
                    Actions = "*/register/action"
                },
                AssignableScopes = $"/subscriptions/{subscriptionId}",
                Scope = $"/subscriptions/{subscriptionId}"
            });

            var roleAssignment = new Assignment(
                "RoleAssignment",
                new AssignmentArgs
            {
                RoleDefinitionName = role.Name,
                PrincipalId = azureADGroup.Id,
                Scope = $"/subscriptions/{subscriptionId}"
            });

            const string resourceGroupName = "Pulumi";
            var resourceGroup = new ResourceGroup(
                "ResourceGroup",
                new ResourceGroupArgs
            {
                Location = "CanadaEast",
                Name = resourceGroupName
            });

            var application = new Application(
                "Application",
                new ApplicationArgs
            {
                Name = "PulumiAzureSetup"
            });

            var servicePrincipal = new ServicePrincipal(
                "ServicePrincipal",
                new ServicePrincipalArgs
            {
                ApplicationId = application.ApplicationId
            });

            var groupMembers = new GroupMember(
                "GroupMembership",
                new GroupMemberArgs
            {
                GroupObjectId = azureADGroup.ObjectId,
                MemberObjectId = servicePrincipal.ObjectId
            });

            var roleAssignmentResourceGroup = new Assignment(
                "RoleAssignmentRG",
                new AssignmentArgs
            {
                RoleDefinitionName = "Contributor",
                PrincipalId = servicePrincipal.Id,
                Scope = $"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}"
            });
        }));
    }
Esempio n. 23
0
    public ApimStack()
    {
        var config = new Pulumi.Config();

        var tenantId = config.Require("tenantId");
        var authorizationEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize";
        var tokenEndpoint         = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
        var defaultScope          = config.Require("scope");
        var clientId     = config.Require("clientId");
        var clientSecret = config.Require("clientSecret");

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("rg-chris-apim");

        //Service Plan
        var appServicePlan = new Plan("plan-api", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "App",
            Sku  = new PlanSkuArgs
            {
                Tier = "Basic",
                Size = "B1"
            }
        });

        var app = new AppService("app-api", new AppServiceArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id
        });

        var apim = new Service("apim-api", new ServiceArgs {
            ResourceGroupName = resourceGroup.Name,
            PublisherName     = "chrisjensenuk",
            PublisherEmail    = "*****@*****.**",
            SkuName           = "Developer_1"
        });

        var apimAuth = new AuthorizationServer("apim-oauth", new AuthorizationServerArgs
        {
            ApiManagementName          = apim.Name,
            ResourceGroupName          = resourceGroup.Name,
            DisplayName                = "apim-oauth",
            ClientRegistrationEndpoint = "http://localhost",
            GrantTypes                  = { "authorizationCode" },
            AuthorizationEndpoint       = authorizationEndpoint,
            AuthorizationMethods        = { "GET", "POST" },
            TokenEndpoint               = tokenEndpoint,
            ClientAuthenticationMethods = "Body",
            BearerTokenSendingMethods   = "authorizationHeader",
            DefaultScope                = defaultScope,
            ClientId     = clientId,
            ClientSecret = clientSecret
        });

        var api = new Api("example-api", new ApiArgs
        {
            ResourceGroupName = resourceGroup.Name,
            ApiManagementName = apim.Name,
            Revision          = "1",
            DisplayName       = "Example API",
            Path      = "example",
            Protocols =
            {
                "https"
            },
            Oauth2Authorization = new ApiOauth2AuthorizationArgs
            {
                AuthorizationServerName = apimAuth.Name
            },
            Import = new ApiImportArgs
            {
                ContentFormat = "openapi+json",
                ContentValue  = Constants.SwaggerJson
            },
            ServiceUrl = app.Name.Apply(n => $"http://{n}.azurewebsites.net")
        });

        var policy = new ApiPolicy("example-api-policy", new ApiPolicyArgs
        {
            ResourceGroupName = resourceGroup.Name,
            ApiManagementName = apim.Name,
            ApiName           = api.Name,
            XmlContent        = Constants.ApiPolicyXml
        });
    }
        private static AppointmentApiAzureResourceBag CreateAppointmentApiAzureResources(AzureResourceBag azureResources, Config config, Input <string> registryImageName)
        {
            var tenantId = config.Require("azure-tenantid");

            var appointmentApiDb = new Database("appointments-api-db", new DatabaseArgs
            {
                ResourceGroupName = azureResources.ResourceGroup.Name,
                Name       = "appointment-api",
                ServerName = azureResources.SqlServer.Name,
                RequestedServiceObjectiveName = "S0",
                Tags = azureResources.Tags
            });

            var image = new Image("appointments-api-docker-image", new ImageArgs
            {
                Build    = $".{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}",
                Registry = new ImageRegistry
                {
                    Server   = azureResources.Registry.LoginServer,
                    Username = azureResources.Registry.AdminUsername,
                    Password = azureResources.Registry.AdminPassword
                },
                ImageName = registryImageName
            }, new ComponentResourceOptions
            {
                DependsOn = new InputList <Resource> {
                    azureResources.Registry
                }
            });

            var appointmentApiIdentity = new UserAssignedIdentity("appointments-api", new UserAssignedIdentityArgs
            {
                ResourceGroupName = azureResources.ResourceGroup.Name,
                Name = "appointments-api",
                Tags = azureResources.Tags
            });

            // AKS service principal needs to have Managed Identity Operator rights over the user assigned identity else AAD pod identity won't work
            var aksSpAppointmentApiAccessPolicy = new Assignment("aks-sp-appontment-api-access", new AssignmentArgs
            {
                PrincipalId        = azureResources.AksServicePrincipal.ObjectId,
                RoleDefinitionName = "Managed Identity Operator",
                Scope = appointmentApiIdentity.Id
            });

            var sqlAdmin = new ActiveDirectoryAdministrator("appointments-api-sql-access", new ActiveDirectoryAdministratorArgs
            {
                ResourceGroupName = azureResources.ResourceGroup.Name,
                TenantId          = tenantId,
                ObjectId          = appointmentApiIdentity.PrincipalId,
                Login             = "******",
                ServerName        = azureResources.SqlServer.Name
            });

            var clientConfig             = Output.Create(GetClientConfig.InvokeAsync());
            var currentPrincipalTenantId = clientConfig.Apply(c => c.TenantId);
            var currentPrincipal         = clientConfig.Apply(c => c.ObjectId);

            var appointmentApiKeyVault = new KeyVault("appointment-api-keyvault", new KeyVaultArgs
            {
                ResourceGroupName = azureResources.ResourceGroup.Name,
                Name = "appointments-api",
                EnabledForDiskEncryption = true,
                TenantId       = tenantId,
                SkuName        = "standard",
                AccessPolicies = new InputList <KeyVaultAccessPolicyArgs>
                {
                    new KeyVaultAccessPolicyArgs
                    {
                        TenantId          = tenantId,
                        ObjectId          = azureResources.AksServicePrincipal.ObjectId,
                        SecretPermissions = new[] { "get", "list" }
                    },
                    new KeyVaultAccessPolicyArgs
                    {
                        TenantId          = tenantId,
                        ObjectId          = appointmentApiIdentity.PrincipalId,
                        SecretPermissions = new[] { "get", "list" }
                    },
                    new KeyVaultAccessPolicyArgs
                    {
                        TenantId          = currentPrincipalTenantId,
                        ObjectId          = currentPrincipal,
                        SecretPermissions = { "delete", "get", "list", "set" },
                    }
                },
                NetworkAcls = new KeyVaultNetworkAclsArgs
                {
                    DefaultAction           = "Deny",
                    Bypass                  = "******",
                    VirtualNetworkSubnetIds = new InputList <string>
                    {
                        azureResources.Subnet.Id
                    },
                    // Need to whitelist the local public IP address otherwise setting secrets will fail
                    IpRules = new InputList <string>
                    {
                        GetMyPublicIpAddress()
                    }
                },
                Tags = azureResources.Tags
            });

            var secret = new Pulumi.Azure.KeyVault.Secret("appointments-api-db-connection-string",
                                                          new Pulumi.Azure.KeyVault.SecretArgs
            {
                KeyVaultId = appointmentApiKeyVault.Id,
                Name       = "ConnectionStrings--PetDoctorContext",
                Value      = Output.Tuple(azureResources.SqlServer.Name, azureResources.SqlServer.Name,
                                          azureResources.SqlServer.AdministratorLogin, azureResources.SqlServer.AdministratorLoginPassword).Apply(
                    t =>
                {
                    var(server, database, administratorLogin, administratorLoginPassword) = t;
                    return
                    ($"Server=tcp:{server}.database.windows.net;Database={database};User ID={administratorLogin};Password={administratorLoginPassword}");
                })
            }, new CustomResourceOptions
            {
                DependsOn = new InputList <Resource>
                {
                    azureResources.SqlServer,
                    appointmentApiKeyVault
                }
            });

            return(new AppointmentApiAzureResourceBag
            {
                Identity = appointmentApiIdentity,
                KeyVault = appointmentApiKeyVault
            });
        }
Esempio n. 25
0
    public AzureStack()
    {
        var config   = new Pulumi.Config();
        var deployTo = config.Require("DeployTo");

        // Create an Azure Resource Group
        var resourceGroupName = $"rg-ne-rpc-demo-{deployTo}";
        var resourceGroup     = new ResourceGroup(resourceGroupName, new ResourceGroupArgs
        {
            Name = resourceGroupName
        });

        // Create an Azure Storage Account
        var storageAccount = new Account($"nerpcdemo{deployTo}", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        // Container for deployment artefacts
        var zipContainer = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        var dataContainer = new Container("data", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
            Name = "data"
        });

        var appServicePlan = new Plan($"plan-{deployTo}", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            }
        });

        var blob = new Blob("azure-func", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = zipContainer.Name,
            Type   = "Block",
            Source = new FileArchive("../azure-func/publish")
        });

        var codeBlobUrl =
            SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var app = new FunctionApp("app", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                  "dotnet"                                                      },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl                                                   },
                { "QuoteServerHost",          "https://vn651r8t22.execute-api.eu-west-2.amazonaws.com/Prod" },
                { "DataConnectionString",     storageAccount.PrimaryBlobConnectionString                    },
                { "DataContainer",            dataContainer.Name                                            }
            },
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            Version = "~3"
        });

        this.StorageAccountName = storageAccount.Name;
        this.Endpoint           = Output.Format($"https://{app.DefaultHostname}/api/lookup");
        this.DataContainer      = dataContainer.Name;
    }
        private static AzureResourceBag CreateBaseAzureInfrastructure(Config config)
        {
            var location = config.Require("azure-location");

            var environment = config.Require("azure-tags-environment");
            var owner       = config.Require("azure-tags-owner");
            var createdBy   = config.Require("azure-tags-createdby");

            var kubernetesVersion   = config.Require("kubernetes-version");
            var kubernetesNodeCount = config.RequireInt32("kubernetes-scaling-nodecount");

            var sqlUser     = config.RequireSecret("azure-sqlserver-username");
            var sqlPassword = config.RequireSecret("azure-sqlserver-password");

            var tags = new InputMap <string>
            {
                { "Environment", environment },
                { "CreatedBy", createdBy },
                { "Owner", owner }
            };

            var resourceGroup = new ResourceGroup("pet-doctor-resource-group", new ResourceGroupArgs
            {
                Name     = "pet-doctor",
                Location = location,
                Tags     = tags
            });

            var vnet = new VirtualNetwork("pet-doctor-vnet", new VirtualNetworkArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name          = "petdoctorvnet",
                AddressSpaces = { "10.0.0.0/8" },
                Tags          = tags
            });

            var subnet = new Subnet("pet-doctor-subnet", new SubnetArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name               = "petdoctorsubet",
                AddressPrefixes    = { "10.240.0.0/16" },
                VirtualNetworkName = vnet.Name,
                ServiceEndpoints   = new InputList <string> {
                    "Microsoft.KeyVault", "Microsoft.Sql"
                }
            });

            var registry = new Registry("pet-doctor-acr", new RegistryArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name         = "petdoctoracr",
                Sku          = "Standard",
                AdminEnabled = true,
                Tags         = tags
            });

            var aksServicePrincipalPassword = new RandomPassword("pet-doctor-aks-ad-sp-password", new RandomPasswordArgs
            {
                Length  = 20,
                Special = true,
            }).Result;

            var clusterAdApp = new Application("pet-doctor-aks-ad-app", new ApplicationArgs
            {
                Name = "petdoctoraks"
            });

            var clusterAdServicePrincipal = new ServicePrincipal("aks-app-sp", new ServicePrincipalArgs
            {
                ApplicationId = clusterAdApp.ApplicationId
            });

            var clusterAdServicePrincipalPassword = new ServicePrincipalPassword("aks-app-sp-pwd", new ServicePrincipalPasswordArgs
            {
                ServicePrincipalId = clusterAdServicePrincipal.ObjectId,
                EndDate            = "2099-01-01T00:00:00Z",
                Value = aksServicePrincipalPassword
            });

            // Grant networking permissions to the SP (needed e.g. to provision Load Balancers)
            var subnetAssignment = new Assignment("pet-doctor-aks-sp-subnet-assignment", new AssignmentArgs
            {
                PrincipalId        = clusterAdServicePrincipal.Id,
                RoleDefinitionName = "Network Contributor",
                Scope = subnet.Id
            });

            var acrAssignment = new Assignment("pet-doctor-aks-sp-acr-assignment", new AssignmentArgs
            {
                PrincipalId        = clusterAdServicePrincipal.Id,
                RoleDefinitionName = "AcrPull",
                Scope = registry.Id
            });

            var logAnalyticsWorkspace = new AnalyticsWorkspace("pet-doctor-aks-log-analytics", new AnalyticsWorkspaceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name = "petdoctorloganalytics",
                Sku  = "PerGB2018",
                Tags = tags
            });

            var logAnalyticsSolution = new AnalyticsSolution("pet-doctor-aks-analytics-solution", new AnalyticsSolutionArgs
            {
                ResourceGroupName   = resourceGroup.Name,
                SolutionName        = "ContainerInsights",
                WorkspaceName       = logAnalyticsWorkspace.Name,
                WorkspaceResourceId = logAnalyticsWorkspace.Id,
                Plan = new AnalyticsSolutionPlanArgs
                {
                    Product   = "OMSGallery/ContainerInsights",
                    Publisher = "Microsoft"
                }
            });

            var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs
            {
                Algorithm = "RSA",
                RsaBits   = 4096,
            });

            var cluster = new KubernetesCluster("pet-doctor-aks", new KubernetesClusterArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name              = "petdoctoraks",
                DnsPrefix         = "dns",
                KubernetesVersion = kubernetesVersion,
                DefaultNodePool   = new KubernetesClusterDefaultNodePoolArgs
                {
                    Name         = "aksagentpool",
                    NodeCount    = kubernetesNodeCount,
                    VmSize       = "Standard_D2_v2",
                    OsDiskSizeGb = 30,
                    VnetSubnetId = subnet.Id
                },
                LinuxProfile = new KubernetesClusterLinuxProfileArgs
                {
                    AdminUsername = "******",
                    SshKey        = new KubernetesClusterLinuxProfileSshKeyArgs
                    {
                        KeyData = sshPublicKey.PublicKeyOpenssh
                    }
                },
                ServicePrincipal = new KubernetesClusterServicePrincipalArgs
                {
                    ClientId     = clusterAdApp.ApplicationId,
                    ClientSecret = clusterAdServicePrincipalPassword.Value
                },
                RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs
                {
                    Enabled = true
                },
                NetworkProfile = new KubernetesClusterNetworkProfileArgs
                {
                    NetworkPlugin    = "azure",
                    ServiceCidr      = "10.2.0.0/24",
                    DnsServiceIp     = "10.2.0.10",
                    DockerBridgeCidr = "172.17.0.1/16"
                },
                AddonProfile = new KubernetesClusterAddonProfileArgs
                {
                    OmsAgent = new KubernetesClusterAddonProfileOmsAgentArgs
                    {
                        Enabled = true,
                        LogAnalyticsWorkspaceId = logAnalyticsWorkspace.Id
                    }
                },
                Tags = tags
            });

            var sqlServer = new SqlServer("pet-doctor-sql", new SqlServerArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name                       = "petdoctorsql",
                Tags                       = tags,
                Version                    = "12.0",
                AdministratorLogin         = sqlUser,
                AdministratorLoginPassword = sqlPassword
            });

            var sqlvnetrule = new VirtualNetworkRule("pet-doctor-sql", new VirtualNetworkRuleArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name       = "petdoctorsql",
                ServerName = sqlServer.Name,
                SubnetId   = subnet.Id,
            });

            var appInsights = new Insights("pet-doctor-ai", new InsightsArgs
            {
                ApplicationType   = "web",
                Name              = "petdoctor",
                ResourceGroupName = resourceGroup.Name,
                Tags              = tags
            });

            var provider = new Provider("pet-doctor-aks-provider", new ProviderArgs
            {
                KubeConfig = cluster.KubeConfigRaw
            });

            return(new AzureResourceBag
            {
                ResourceGroup = resourceGroup,
                SqlServer = sqlServer,
                Cluster = cluster,
                ClusterProvider = provider,
                AppInsights = appInsights,
                AksServicePrincipal = clusterAdServicePrincipal,
                Subnet = subnet,
                Registry = registry,
                Tags = tags
            });
        }
Esempio n. 27
0
    public DevOpsInfra()
    {
        _config = new Config("ado");

        #pragma warning disable
        Pulumi.InputMap <string> tags = JsonConvert.DeserializeObject <Dictionary <string, string> >(_config.RequireObject <JsonElement>("tags").ToString());

        #region AzureNative.Resources.ResourceGroup (-rg)
        var resourceGroup = new Pulumi.AzureNative.Resources.ResourceGroup($"{_config.Require("resourceGroup")}-{_config.Require("env")}-rg-", new Pulumi.AzureNative.Resources.ResourceGroupArgs
        {
            Location = _config.Require("location"),
            Tags     = tags,
        });
        this.ResourceGroupName = resourceGroup.Name;
        #endregion

        #region NetworkSecurityGroup (-nsg)
        // NSGs can be connected to Subnets or Network cards (NICs).
        // When applied to the subnet, the NSG applies to all VMs on that subnet. If you apply only to the NIC card, just that one VM is affected.
        string myIp = new System.Net.WebClient().DownloadString("https://api.ipify.org");
        var    networkSecurityGroup = new Pulumi.AzureNative.Network.NetworkSecurityGroup($"{_config.Require("vnet.name")}-{_config.Require("env")}-nsg-", new Pulumi.AzureNative.Network.NetworkSecurityGroupArgs
        {
            ResourceGroupName = resourceGroup.Name,
            SecurityRules     =
            {
                new Pulumi.AzureNative.Network.Inputs.SecurityRuleArgs
                {
                    Name                     = "allow-rdp",
                    Protocol                 = SecurityRuleProtocol.Tcp,
                    SourcePortRange          = "*",
                    DestinationPortRange     = "3389",
                    SourceAddressPrefix      = myIp,
                    DestinationAddressPrefix = "*",
                    Access                   = "Allow",
                    Priority                 = 300,
                    Direction                = "Inbound",
                },

                new Pulumi.AzureNative.Network.Inputs.SecurityRuleArgs
                {
                    Name                     = "allow-http", // _config.Require("nsg.name"),
                    Protocol                 = SecurityRuleProtocol.Tcp,
                    SourcePortRange          = "*",
                    DestinationPortRange     = "443",
                    SourceAddressPrefix      = "*",
                    DestinationAddressPrefix = "*",
                    Access                   = "Allow",
                    Priority                 = 301,
                    Direction                = "Inbound",
                },
            },
        });
        #endregion

        #region VirtualNetwork (-vnet)
        var network = new VirtualNetwork($"{_config.Require("vnet.name")}-{_config.Require("env")}-vnet-",
                                         new VirtualNetworkArgs
        {
            AddressSpace = new Pulumi.AzureNative.Network.Inputs.AddressSpaceArgs
            {
                AddressPrefixes =
                {
                    _config.Require("vnet.cidr"),
                },
            },
            Location          = _config.Require("location"),
            ResourceGroupName = resourceGroup.Name,
            Subnets           =
            {
                new Pulumi.AzureNative.Network.Inputs.SubnetArgs
                {
                    AddressPrefix = _config.Require("bastion.cidr"),
                    Name          = "AzureBastionSubnet",
                },
                new Pulumi.AzureNative.Network.Inputs.SubnetArgs
                {
                    AddressPrefix        = _config.Require("snet.cidr"),
                    Name                 = _config.Require("snet.name"),
                    NetworkSecurityGroup = new Pulumi.AzureNative.Network.Inputs.NetworkSecurityGroupArgs
                    {
                        Id = networkSecurityGroup.Id,
                    },
                },
            },
            VirtualNetworkName = "AzureDevOps",
            // VirtualNetworkPeerings
            EnableDdosProtection = false,
        }
                                         );
        #endregion

        #region PublicIp (-ip)
        var publicIp = new Pulumi.AzureNative.Network.PublicIPAddress($"bastion-{_config.Require("env")}-ip-", new Pulumi.AzureNative.Network.PublicIPAddressArgs
        {
            PublicIPAddressVersion   = IPVersion.IPv4,
            PublicIPAllocationMethod = IPAllocationMethod.Static,
            IdleTimeoutInMinutes     = 4,
            Location          = _config.Require("location"),
            ResourceGroupName = resourceGroup.Name,
            Sku = new Pulumi.AzureNative.Network.Inputs.PublicIPAddressSkuArgs
            {
                Name = PublicIPAddressSkuName.Standard,
                Tier = PublicIPAddressSkuTier.Regional,
            },
        });
        var vmPublicIp = new Pulumi.AzureNative.Network.PublicIPAddress($"{_config.Require("agent.name")}-{_config.Require("env")}-ip-", new Pulumi.AzureNative.Network.PublicIPAddressArgs
        {
            PublicIPAddressVersion   = IPVersion.IPv4,
            PublicIPAllocationMethod = IPAllocationMethod.Static,
            IdleTimeoutInMinutes     = 4,
            Location          = _config.Require("location"),
            ResourceGroupName = resourceGroup.Name,
            Sku = new Pulumi.AzureNative.Network.Inputs.PublicIPAddressSkuArgs
            {
                Name = PublicIPAddressSkuName.Standard,
                Tier = PublicIPAddressSkuTier.Regional,
            },
        });

        #endregion

        #region NetworkInterface (-nic)
        var networkInterface = new Pulumi.AzureNative.Network.NetworkInterface($"{_config.Require("agent.name")}-{_config.Require("env")}-nic-", new Pulumi.AzureNative.Network.NetworkInterfaceArgs
        {
            // AdoAgent has size Standard_B2s, which is not compatible with  accelerated networking on network interface.
            // https://docs.microsoft.com/en-us/azure/virtual-network/create-vm-accelerated-networking-powershell
            // EnableAcceleratedNetworking = true,
            IpConfigurations =
            {
                new Pulumi.AzureNative.Network.Inputs.NetworkInterfaceIPConfigurationArgs
                {
                    Name    = "ipconfig1",
                    Primary = true,
                    PrivateIPAllocationMethod = IPAllocationMethod.Dynamic,
                    PrivateIPAddressVersion   = "IPv4",
                    PublicIPAddress           = new Pulumi.AzureNative.Network.Inputs.PublicIPAddressArgs
                    {
                        Id = vmPublicIp.Id,
                    },
                    Subnet = new Pulumi.AzureNative.Network.Inputs.SubnetArgs
                    {
                        #pragma warning disable
                        Id = network.Subnets.Apply(s => s[1].Id),
                    },
                },
            },
            Location          = _config.Require("location"),
            ResourceGroupName = resourceGroup.Name,
        });
        #endregion

        #region VirtualMachine (-vm)
        var vm = new Pulumi.AzureNative.Compute.VirtualMachine($"{_config.Require("agent.name")}-{_config.Require("env")}-vmi-", new Pulumi.AzureNative.Compute.VirtualMachineArgs
        {
            ResourceGroupName = resourceGroup.Name,
            HardwareProfile   = new Pulumi.AzureNative.Compute.Inputs.HardwareProfileArgs {
                VmSize = _config.Require("vm.vmSize")
            },
            VmName             = "AdoAgent",
            DiagnosticsProfile = new Pulumi.AzureNative.Compute.Inputs.DiagnosticsProfileArgs
            {
                BootDiagnostics = new Pulumi.AzureNative.Compute.Inputs.BootDiagnosticsArgs {
                    Enabled = true
                }
            },
            NetworkProfile = new Pulumi.AzureNative.Compute.Inputs.NetworkProfileArgs
            {
                NetworkInterfaces =
                {
                    new Pulumi.AzureNative.Compute.Inputs.NetworkInterfaceReferenceArgs
                    {
                        Id      = networkInterface.Id,
                        Primary = true,
                    },
                }
            },
            StorageProfile = new Pulumi.AzureNative.Compute.Inputs.StorageProfileArgs
            {
                ImageReference = new Pulumi.AzureNative.Compute.Inputs.ImageReferenceArgs
                {
                    Publisher = "MicrosoftWindowsServer",
                    Offer     = "WindowsServer",
                    Sku       = "2019-Datacenter-with-Containers-smalldisk",
                    Version   = "latest"
                },

                OsDisk = new Pulumi.AzureNative.Compute.Inputs.OSDiskArgs
                {
                    OsType       = Pulumi.AzureNative.Compute.OperatingSystemTypes.Windows,
                    Name         = "system",
                    CreateOption = Pulumi.AzureNative.Compute.DiskCreateOptionTypes.FromImage,
                    Caching      = Pulumi.AzureNative.Compute.CachingTypes.ReadWrite,
                    ManagedDisk  = new Pulumi.AzureNative.Compute.Inputs.ManagedDiskParametersArgs
                    {
                        StorageAccountType = Pulumi.AzureNative.Compute.StorageAccountTypes.Standard_LRS,
                    },
                    DiskSizeGB = 100,
                },

                DataDisks =
                {
                    new Pulumi.AzureNative.Compute.Inputs.DataDiskArgs
                    {
                        Name         = "Data",
                        CreateOption = Pulumi.AzureNative.Compute.DiskCreateOptionTypes.Empty,
                        DiskSizeGB   = _config.RequireInt32("vm.diskSizeGB"),
                        Lun          = 0,
                        Caching      = Pulumi.AzureNative.Compute.CachingTypes.None,
                    },
                },
            },
            OsProfile = new Pulumi.AzureNative.Compute.Inputs.OSProfileArgs
            {
                ComputerName         = _config.Require("agent.name"),
                AdminUsername        = _config.Require("admin.user"),
                AdminPassword        = _config.RequireSecret("admin.pw"),
                WindowsConfiguration = new Pulumi.AzureNative.Compute.Inputs.WindowsConfigurationArgs
                {
                    ProvisionVMAgent       = true,
                    EnableAutomaticUpdates = true,
                    PatchSettings          = new Pulumi.AzureNative.Compute.Inputs.PatchSettingsArgs
                    {
                        PatchMode         = Pulumi.AzureNative.Compute.WindowsVMGuestPatchMode.AutomaticByOS,
                        EnableHotpatching = false,
                    },
                },
            },
        });     // new CustomResourceOptions { DeleteBeforeReplace = true });
        #endregion

        #region BastionHost (-bas)
        // Azure Bastion is a fully managed PaaS service that provides secure and seamless RDP and SSH access to virtual machines through the Azure Portal.
        // A BastionHost is provisioned within a Virtual Network (VNet) to provid SSL access to all VMs in the VNet without exposure through public IP addresses.
        var bastionHost = new Pulumi.AzureNative.Network.BastionHost($"{_config.Require("vnet.name")}-{_config.Require("env")}-bas-", new Pulumi.AzureNative.Network.BastionHostArgs
        {
            Location          = resourceGroup.Location,
            ResourceGroupName = resourceGroup.Name,
            IpConfigurations  =
            {
                new Pulumi.AzureNative.Network.Inputs.BastionHostIPConfigurationArgs
                {
                    Name            = "bastionHostIpConfiguration",
                    PublicIPAddress = new Pulumi.AzureNative.Network.Inputs.SubResourceArgs
                    {
                        Id = publicIp.Id,
                    },
                    Subnet = new Pulumi.AzureNative.Network.Inputs.SubResourceArgs
                    {
                        Id = network.Subnets.Apply(s => s[0].Id),
                    },
                },
            },
        });
        #endregion
    }
Esempio n. 28
0
    public RecipeBankStack()
    {
        var config        = new Pulumi.Config();
        var resourceGroup = new ResourceGroup("RecipeBank");

        // Create an Azure Storage Account
        var storageAccount = new Account("storage", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
            EnableHttpsTrafficOnly = true
        });

        var clientConfig     = Output.Create(Pulumi.Azure.Core.Invokes.GetClientConfig());
        var tenantId         = clientConfig.Apply(c => c.TenantId);
        var currentPrincipal = clientConfig.Apply(c => c.ObjectId);

        // Key Vault to store secrets
        var vault = new KeyVault("vault", new KeyVaultArgs
        {
            ResourceGroupName = resourceGroup.Name,
            SkuName           = "standard",
            TenantId          = tenantId,
            AccessPolicies    =
            {
                new KeyVaultAccessPoliciesArgs
                {
                    TenantId = tenantId,
                    // The current principal has to be granted permissions to Key Vault so that it can actually add and then remove
                    // secrets to/from the Key Vault. Otherwise, 'pulumi up' and 'pulumi destroy' operations will fail.
                    ObjectId          = currentPrincipal,
                    SecretPermissions ={ "delete",                         "get", "list", "set" },
                }
            },
        });

        // A plan to host the App Service
        var appServicePlan = new Plan("api", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind     = "Linux",
            Reserved = true,
            Sku      = new PlanSkuArgs
            {
                Tier = "Free",
                Size = "F1",
            },
        });

        // The application hosted in App Service
        var app = new AppService("api", new AppServiceArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            // A system-assigned managed service identity to be used for authentication and authorization to the Storage
            Identity = new AppServiceIdentityArgs {
                Type = "SystemAssigned"
            },
            AppSettings =
            {
                { "KeyVaultName", vault.Name }
            },
            HttpsOnly = true,
            Logs      = new AppServiceLogsArgs()
            {
                HttpLogs = new AppServiceLogsHttpLogsArgs()
                {
                    FileSystem = new AppServiceLogsHttpLogsFileSystemArgs()
                    {
                        RetentionInDays = 20,
                        RetentionInMb   = 30
                    }
                }
            }
        });

        // Work around a preview issue https://github.com/pulumi/pulumi-azure/issues/192
        var principalId = app.Identity.Apply(id => id.PrincipalId ?? "11111111-1111-1111-1111-111111111111");

        // Grant App Service access to KV secrets
        var policy = new AccessPolicy("app-policy", new AccessPolicyArgs
        {
            KeyVaultId = vault.Id,
            TenantId   = tenantId,
            ObjectId   = principalId,
            // The .NET's KeyVault config provider needs the list permission to enumerate the secrets
            SecretPermissions = { "get", "list" },
        });

        // From pulumi secrets
        var dbConnectionStringSecret = new Secret("dbConnectionString", new SecretArgs()
        {
            KeyVaultId = vault.Id,
            Name       = "DBConnectionString",
            Value      = config.Require("dbConnectionString")
        });

        this.Endpoint = Output.Format($"https://{app.DefaultSiteHostname}");
    }